<?php

namespace Biz\module\Classes;

use Biz\cache\ConfirmOrder as ConfirmOrderCache;
use Biz\model\activity\PinTuan as mPinTuan;
use Biz\model\GoodsBasicInfo as mGoodsBasicInfo;
use Biz\model\GoodsExtendInfo as mGoodsExtendInfo;
use Biz\model\GoodsSku as mGoodsSku;
use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderExtend as mOrderExtend;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderParent as mOrderParent;
use Biz\model\trade\OrderRefundQueue as mOrderRefundQueue;
use Biz\module\Behaviors\Order\OrderFormat;
use Biz\module\Classes\Coupon as clsCoupon;
use Biz\module\Classes\ShopCoupon as clsShopCoupon;
use Biz\module\Packages\OrderAmount\OrderAmount;
use Biz\module\Sys\ErrorConst;
use Biz\pockets\constInterface\ActivityInfo as constActivityInfo;
use Biz\pockets\constInterface\TheParagraphStore;
use Biz\pockets\serviceTrait\_Async;
use Biz\service\Event;
use Biz\service\Group as sGroup;
use Biz\service\redPacket\RedPackets as sRedPackets;
use Biz\service\salesRebate\SalesOrder as sSalesOrder;
use Biz\service\salesRebate\SalesRebate as sSalesRebate;
use Biz\service\settlement\SettlementTransaction;
use Biz\service\ShopCommissionRate;
use Biz\service\ShopSpecial as sShopSpecial;
use Biz\service\Sku as sSku;
use Biz\service\Stock as sStock;
use Biz\service\theParagraph\Store as sStore;
use Biz\service\trade\Integral as sIntegral;
use Biz\service\trade\UserAddress as UserAddressService;
use Biz\tools\OrderNo as toolOrderNo;
use Doraemon\amqp\Queue;
use Doraemon\model\Phone;
use Doraemon\pockets\constInterface\AppType;
use Doraemon\service\Member\PhoneCrypto;
use Doraemon\tools\HhzClient;
use Doraemon\tools\HhzClient as tHhzClient;
use Doraemon\tools\Log as toolsLog;
use hhz\constant\basic\findPhoneScene;
use Medoo\Medoo;

final class Order
{
    use _Async;

    const FIFTEEN_DAYS_SHIPPING_ICON = 'http://img.hhz1.cn/Op-imageShow/91fbe30160190vi00pv189u?iv=1';
    const SKU_TIP_ICON = 'http://img.hhz1.cn/Op-imageShow/0df4d30130130cd00plcum5?iv=1';
    const FULL_SHIPPING_ICON = 'http://img.hhz1.cn/Op-imageShow/f1609302o0100EW00pifkvn?iv=1';

    const PHONE_DECRYPT_MIRROR = 'magic_mirror_decrypt_shop_order';

    private static $eventId = 0;

    /**
     * 确认订单列表
     * @param $uid
     * @param array $submitSku ["sku_id"=>1,"buy_num"=>2] 要结算的sku信息
     * @param $areaCode 地区code（市）
     * @param int $source 订单来源 1:购物车 2：立即购买
     * @param null $accept_id $acceptId 地址簿id
     * @param null $skuToken
     * @param null $couponId 优惠券id
     * @param null $couponVid
     * @param array $sCouponInfo 店铺优惠券信息
     * @param null $mealId 套餐id
     * @param int $useIntegral 是否使用积分
     * @param int $usePacket 是否使用红包
     * @param int $appType app来源
     * @param int $storeId 节选店铺id
     * @param int $isSelfMention 是否店铺自提
     * @param int $activityId 活动id（拼团活动id）
     * @param int $activityType 活动类型
     * @param int $teamJoinId 参团id
     * @return array
     * @throws \Exception
     */
    public static function confirmOrderList($uid, array $submitSku, $areaCode, $source = 1, $accept_id = null, $skuToken = null, $couponId = null, $couponVid = null, $sCouponInfo = [], $mealId = null, $useIntegral = 1, $usePacket = 1, $appType = 1, $storeId = 0, $isSelfMention = 0, $activityId = 0, $activityType = 0, $teamJoinId = 0)
    {
        $isParagraph = $appType == AppType::APPTYPE_PARAGRAPH_MINIPROGRAM;
        if (!$isParagraph) {
//            throw new \Exception('提交订单失败。好好住商城已升级为「好物」，请更新至最新版本App查看', -1);
        }
        $result = [
            "accept_info" => [],//收货人信息
            "list" => [], //店铺商品列表
            "integral" => [//积分信息
                'total' => 0,
                'usable' => 0,
                'discount' => 0,
                'text' => ''
            ],
            "summary" => [//汇总信息
                "goods_amount" => 0,
                "total_amount" => 0,
                "total_buynum" => 0
            ],
            "sku_token" => "",
            "is_can_create" => 1,//是否可以下单
            'create_param' => [
                'activity_type' => $activityType,
                'activity_id' => $activityId,
                'team_join_id' => $teamJoinId
            ]
        ];

        //获取收货信息
        $acceptRs = self::getAcceptInfo($accept_id, $areaCode, $uid);
        $areaCode = $acceptRs['areaCode'];
        $result['accept_info'] = $acceptRs['acceptInfo'];

        //购买商品处理
        $selfMentionId = ($storeId && $isSelfMention) ? $storeId : 0;
        $skuNumList = [];
        $isToken = false;
        if ($skuToken) {
            $cacheJson = ConfirmOrderCache::getConfirmInfo($uid, $skuToken);
            if (!$cacheJson) {
                toolsLog::order_confirmOrderList_warning('订单信息skutoken失效或则过期', [
                    'uid' => $uid,
                    'sku_token' => $skuToken,
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_INFO_INVALID], -1);
            }
            $cacheData = json_decode($cacheJson, true);
            $skuInfoList = $cacheData['list'];
            $isToken = true;
        } else {
            self::checkConfirmData($uid, $submitSku, $mealId, $activityType, $activityId);
            foreach ($submitSku as $row) {
                $skuNumList[$row['sku_id']] = $row['buy_num'];
            }
            $skuIds = array_keys($skuNumList);
            $skuInfoList = sSku::Sku4Order($skuIds, ($activityId && $activityType) ? ['activity_id' => $activityId, 'type' => $activityType] : []);
            toolsLog::order_createOrder_info('购买信息', compact('skuNumList', 'skuInfoList'));
            self::checkConfirmSku($uid, $skuNumList, $skuInfoList, $mealId, $activityId, $activityType, $teamJoinId);
        }
        $computerOrder = new OrderFormat($skuNumList);
        $orderData = $computerOrder->computeConfirmOrder($uid, $skuInfoList, $areaCode, $isToken, $sCouponInfo, $couponId, 0, $mealId, $selfMentionId);

        $data = $orderData;
        $data['source'] = $source;
        $data['sku_token'] = self::createSkuToken($uid, $data);
        toolsLog::order_createOrder_info('获取订单信息成功', [
            'uid' => $uid,
            'selfMentionId' => $selfMentionId,
            'orderData' => $orderData,
            'sku_token' => $data['sku_token'],
        ]);
        $result['list'] = [];
        $receiveShippingGoods = null;
        if ($isParagraph) {//节选小程序
            $supportShipping = true;
            foreach ($data['support_shipping'] as $shopId => $supportShippingArr) {
                if (!$supportShipping) {
                    break;
                } else if (!$supportShippingArr['support']) {
                    $supportShipping = false;
                }
            }
            if (!$supportShipping) {
                $result['is_can_create'] = $selfMentionId > 0 ? 1 : 0;
                $result['accept_info']['accept_tip'] = [
                    'icon' => '',
                    'text' => '由于「the Paragraph 节选」仍在试运营阶段，部分商品无法寄送到您指定的收货地址，敬请谅解。',
                ];
            }
        }
        if (version_compare(tHhzClient::getClientVersion(), '3.6.0', '>=')) {
            $mealDetractAmount = 0;
            $couponDetractAmount = 0;
            if (isset($data['coupon']) && $data['coupon'] && $data['coupon']['detract_amount'] > 0) {
                $couponDetractAmount = bcadd($couponDetractAmount, $data['coupon']['detract_amount'], 2);
            }
            $shopCouponDetractAmount = 0;
            foreach ($data['list'] as $shopId => $shopOrder) {
                $result['list'][$shopId]['coupon'] = $shopOrder['coupon'] ? $shopOrder['coupon'] : null;
                $result['list'][$shopId]['meal'] = $shopOrder['meal'] ? $shopOrder['meal'] : null;
                $result['list'][$shopId]['shop_info'] = $shopOrder['shop_info'];
                $result['list'][$shopId]['summary'] = $shopOrder['summary'];
                if (isset($shopOrder['coupon']) && $shopOrder['coupon'] && $shopOrder['coupon']['detract_amount'] > 0) {
                    $shopCouponDetractAmount = bcadd($shopCouponDetractAmount, $shopOrder['coupon']['detract_amount'], 2);
                }
                $supportShippingArr = isset($data['support_shipping'][$shopId]) ? $data['support_shipping'][$shopId] : [];
                $weekPurchaseIcon = [];
                foreach ($shopOrder['sku_list'] as $skuInfo) {
                    $skuTips = [];
                    $skuTip = null;
                    if ($supportShippingArr && in_array($skuInfo['goods_id'], $supportShippingArr['nonsupport_goods'])) {
                        $supportArea = $supportShippingArr['support_area'][$skuInfo['goods_id']];
                        $skuTip = [
                            'icon' => self::SKU_TIP_ICON,
                            'text' => '当前地区无法配送',
                            'desc' => '',
                        ];
                        if ($appType == AppType::APPTYPE_PARAGRAPH_MINIPROGRAM) {//节选小程序
                            $skuTip['text'] = '部分地区配送';
                            $skuTip['desc'] = '由于「the Paragraph 节选」仍在试运营阶段，该商品收货地址仅限' . $supportArea . '，其他地区将逐渐开放，敬请谅解。';
                        }
                        $skuTips[] = $skuTip;
                    } else if ($couponId) {
                        if ($appType == AppType::APPTYPE_PARAGRAPH_MINIPROGRAM && $data['coupon_sku']) {
                            if (!isset($data['coupon_sku'][$skuInfo['sku_id']]) || !$data['coupon_sku'][$skuInfo['sku_id']]) {
                                $skuTip['text'] = '该商品无法使用此优惠券';
                                $skuTip['direction'] = 'right';
                                $skuTips[] = $skuTip;
                            }
                        }
                    } else {
                        $tipText = '';
                        if ($skuInfo['shipping_info']['type'] == mGoodsExtendInfo::SHIPPING_TIME_TYPE_PRE_SALE) {
                            $tipText = $skuInfo['shipping_info']['shipping_time'] . '发货';
                        }
                        if (strtotime($skuInfo['forecast_ship_time']) > 0 && strtotime($skuInfo['forecast_ship_time']) > time()) {
                            $tipText = date('Y年m月d日', strtotime($skuInfo['forecast_ship_time'])) . '后发货';
                        }
                        if ($tipText) {
                            $skuTip = ['icon' => self::FIFTEEN_DAYS_SHIPPING_ICON, 'text' => $tipText];
                            $skuTips[] = $skuTip;
                        }
                        if ($skuInfo['activity_type'] == constActivityInfo::ACTIVITY_TYPE_LIMIT_TIME_ROB) {
                            $skuTips[] = ['icon' => self::SKU_TIP_ICON, 'text' => '限时购商品不支持与其他优惠共享'];
                            if (!$tipText) {
                                $skuTip = ['icon' => self::SKU_TIP_ICON, 'text' => '限时购商品不支持与其他优惠共享'];
                            }
                        }
                    }
                    $skuInfo['sku_tip'] = $skuTip;
                    $skuInfo['sku_tips'] = $skuTips;
                    $skuInfo['active_icon_list'] = [];
                    if (!$isParagraph) {
                        if ($skuInfo['activity_type'] == constActivityInfo::ACTIVITY_TYPE_PINTUAN && $activityId) {
                            $pingTuanInfo = mPinTuan::getInfo(['id' => $activityId, 'status' => mPinTuan::STATUS_NORMAL], ['id', 'cover_img']);
                            if ($pingTuanInfo) {
                                $skuInfo['active_icon_list'][] = $pingTuanInfo['cover_img_url'];
                            }
                        }
                        if ($shopOrder['full_shipping_goods_ids'] && in_array($skuInfo['goods_id'], $shopOrder['full_shipping_goods_ids'])) {
                            $skuInfo['active_icon_list'][] = self::FULL_SHIPPING_ICON;
                        }
                    } else {
                        if ($skuInfo['activity_type'] == constActivityInfo::ACTIVITY_TYPE_WEEK_PURCHASE) {
                            if (!isset($weekPurchaseIcon[$skuInfo['goods_id']])) {
                                $activityData = sShopSpecial::getActivityData($skuInfo['activity_id']);
                                if ($activityData['special_icon']) {
                                    $weekPurchaseIcon[$skuInfo['goods_id']] = $activityData['special_icon'];
                                } else {
                                    $weekPurchaseIcon[$skuInfo['goods_id']] = [];
                                }
                            }
                            $skuInfo['active_icon_list'][] = $weekPurchaseIcon[$skuInfo['goods_id']];
                        }
                    }
                    $result['list'][$shopId]['sku_list'][] = $skuInfo;
                }
                $result['list'][$shopId]['amount_struct'][] = [
                    'name' => '运费',
                    'icon' => '',
                    'text' => $shopOrder['summary']['shipping_fee'] > 0 ? '¥' . $shopOrder['summary']['shipping_fee'] : '包邮',
                    'type' => 1,
                ];
                if ($shopOrder['summary']['full_shipping_plan_id'] && $shopOrder['summary']['shipping_fee'] != $shopOrder['summary']['shipping_amount']) {
                    $result['list'][$shopId]['amount_struct'][] = [
                        'name' => '运费优惠',
                        'icon' => self::FULL_SHIPPING_ICON,
                        'text' => '-¥' . bcsub($shopOrder['summary']['shipping_fee'], $shopOrder['summary']['shipping_amount'], 2),
                        'type' => 2,
                    ];
                }
                if ($shopOrder['meal'] && $shopOrder['meal']['detract_amount'] > 0) {
                    $mealDetractAmount = $shopOrder['meal']['detract_amount'];
                    $result['list'][$shopId]['amount_struct'][] = [
                        'name' => '套餐优惠',
                        'icon' => '',
                        'text' => '-¥' . $shopOrder['meal']['detract_amount'],
                        'type' => 2,
                    ];
                }
            }
            $result['amount_struct'][] = [
                'name' => '商品金额',
                'icon' => '',
                'text' => '¥' . $data['summary']['goods_amount'],
                'type' => 1,
            ];
            $result['amount_struct'][] = [
                'name' => '运费',
                'icon' => '',
                'text' => $data['summary']['shipping_fee'] > 0 ? '¥' . $data['summary']['shipping_fee'] : '包邮',
                'type' => 1,
            ];
            if ($data['summary']['shipping_fee'] != $data['summary']['shipping_amount']) {
                $result['amount_struct'][] = [
                    'name' => '运费优惠',
                    'icon' => '',
                    'text' => '-¥' . bcsub($data['summary']['shipping_fee'], $data['summary']['shipping_amount'], 2),
                    'type' => 2,
                ];
            }
            if ($mealDetractAmount) {
                $result['amount_struct'][] = [
                    'name' => '套餐优惠',
                    'icon' => '',
                    'text' => '-¥' . $mealDetractAmount,
                    'type' => 2,
                ];
            }
            if ($shopCouponDetractAmount) {
                $result['amount_struct'][] = [
                    'name' => '店铺优惠券',
                    'icon' => '',
                    'text' => '-¥' . $shopCouponDetractAmount,
                    'type' => 2,
                ];
            }
            if ($couponDetractAmount) {
                $result['amount_struct'][] = [
                    'name' => '平台优惠券',
                    'icon' => '',
                    'text' => '-¥' . $couponDetractAmount,
                    'type' => 2,
                ];
            }
        } else {
            //小于3.6.0的版本返回的数据格式
            foreach ($data['list'] as $shopId => $list) {
                $result['list'][$shopId]['sku_list'] = [];
                foreach ($list['sku_list'] as $skuInfo) {
                    $result['list'][$shopId]['sku_list'][] = [
                        'sku_id' => $skuInfo['sku_id'],
                        'goods_id' => $skuInfo['goods_id'],
                        'title' => $skuInfo['title'],
                        'cover_img' => $skuInfo['cover_img'],
                        'spec_img' => $skuInfo['spec_img'],
                        'sku_desc' => $skuInfo['sku_desc'],
                        'sell_price' => $skuInfo['ori_price'],// 售卖价格
                        'buy_price' => $skuInfo['actual_price'],// 购买价格
                        'buy_num' => $skuInfo['buy_num'],
                        'stock' => $skuInfo['actual_stock'],
                        'weight' => $skuInfo['weight'],
                        'sku_tip' => $skuInfo['sku_tip'],
                        'activity_type' => $skuInfo['activity_type'],
                        'activity_id' => $skuInfo['activity_id'],
                    ];
                }
                $result['list'][$shopId]['summary'] = $list['summary'];
            }
        }
        $result['list'] = array_values($result['list']);
        $result['summary'] = $data['summary'];
        $result['integral'] = $data['integral'] ? $data['integral'] : null;
        if (self::zyjtVersion()) $result['integral'] = null;
        if ($result['integral']) {
            $result['integral']['use_integral'] = $useIntegral ? 1 : 0;
            if ($useIntegral && $result['integral']['discount'] > 0) {
                $result['amount_struct'][] = [
                    'name' => '积分优惠',
                    'icon' => '',
                    'text' => '-¥' . $result['integral']['discount'],
                    'type' => 2,
                ];
            }
        }
        $result['coupon'] = $data['coupon'] ? $data['coupon'] : null;
        $result['red_packet'] = $data['red_packet'] ? $data['red_packet'] : null;
        if ($result['red_packet']) {
            $result['red_packet']['use_packet'] = $usePacket ? 1 : 0;
            if ($usePacket && $result['red_packet']['packet_amount'] > 0) {
                $result['amount_struct'][] = [
                    'name' => '现金红包',
                    'icon' => '',
                    'text' => '-¥' . $result['red_packet']['packet_amount'],
                    'type' => 2,
                ];
            }
        }
        $result['sku_token'] = $data['sku_token'];
        if ($result['summary']['goods_amount'] > mOrder::MAX_CREATE_ORDER_AMOUNT) { //金额超过5万的订单无法支付，请分开下单
            $errArr = [
                'uid' => $uid,
                'goods_amount' => $result['summary']['goods_amount'],
            ];
            $msg = '金额超过' . (mOrder::MAX_CREATE_ORDER_AMOUNT / 10000) . '万的订单无法支付，请分开下单';
            toolsLog::order_confirmOrderList_warning($msg, $errArr);
            throw new \Exception($msg, -1);
        }

        if ($isParagraph) {//节选小程序,增加自提店铺
            $result['self_mention'] = sStore::getSelfMentionList();
        }
        return $result;
    }

    public static function getAcceptInfo($accept_id, $areaCode, $uid)
    {
        if ($accept_id) {
            $acceptInfo = UserAddressService::getByAcceptId($accept_id);
            if (!$acceptInfo) {
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_ACCEPT_NOT_EXISTS], -1);//收货地址不存在
            }
        } else {
            $acceptInfo = UserAddressService::getDefaultAddress($uid);;//获取默认收货地址
        }
        if ($acceptInfo) {
            $areaCode = $acceptInfo['city'];
            unset($acceptInfo['uid']);
            unset($acceptInfo['info_address']);
            unset($acceptInfo['is_default']);
            unset($acceptInfo['addtime']);
        } else {
            $acceptInfo = null;
        }
        return compact('acceptInfo', 'areaCode');
    }

    private static function checkConfirmData($uid, array $submitSku, $mealId, $activityType, $activityId)
    {
        if (count($submitSku) > mOrder::MAX_CREATE_ORDER_GOODS_NUM) {
            throw new \Exception('最多可以购买' . mOrder::MAX_CREATE_ORDER_GOODS_NUM . '个商品', -1);//最多购买50个商品
        }
        if ($mealId && count($submitSku) < 2) {//套餐必须至少两个商品sku
            $errArr = [
                'uid' => $uid,
                'submit_sku' => $submitSku,
            ];
            toolsLog::order_confirmOrderList_warning('套餐至少有两个商品', $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "获取确认订单信息失败，套餐至少有两个商品:#date:" . date('YmdHis') . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], -1);
        }
        if ($activityType && $activityId && $activityType == constActivityInfo::ACTIVITY_TYPE_PINTUAN && count($submitSku) > 1) {//拼团只能一次购买一个商品
            $errArr = [
                'uid' => $uid,
                'submit_sku' => $submitSku,
            ];
            $msg = '拼团下单一次只能购买一个商品';
            toolsLog::order_confirmOrderList_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . ":#date:" . date('YmdHis') . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], -1);
        }
        foreach ($submitSku as $row) {
            if ($mealId && $row['buy_num'] > 1) {
                $errArr = [
                    'uid' => $uid,
                    'meal_id' => $mealId,
                    'sku_id' => $row['sku_id'],
                    'buy_num' => $row['buy_num']
                ];
                toolsLog::order_confirmOrderList_warning('套餐单个sku数量只能是1个', $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => "获取确认订单信息失败，套餐单个sku数量不正确:#date:" . date('YmdHis') . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], -1);
            }
            if ($row['buy_num'] <= 0 || floor($row['buy_num']) != $row['buy_num']) {
                $errArr = [
                    'uid' => $uid,
                    'sku_id' => $row['sku_id'],
                    'buy_num' => $row['buy_num']
                ];
                toolsLog::order_confirmOrderList_warning('商品购买数量不正确', $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => "获取确认订单信息失败，商品购买数量不正确:#date:" . date('YmdHis') . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], -1);//异常提交数据 购买数为负数
            }
        }
    }

    /**
     * 提交订单
     * @param $uid
     * @param $skuToken
     * @param $acceptId 地址簿id
     * @param $messageInfo 店铺留言信息
     * @param $integral 使用积分
     * @param $packetAmount 使用红包
     * @param $couponId 优惠券id
     * @param $couponVid 用户获取的优惠券唯一标
     * @param array $sCouponInfo 店铺优惠券信息
     * @param int $appType app来源
     * @param int $mealId 套餐id
     * @param int $storeId 节选店铺id
     * @param int $isSelfMention 是否店铺自提
     * @param int $activityId 活动id（拼团活动id）
     * @param int $activityType 活动类型
     * @param int $teamJoinId 参团id
     * @return array
     * @throws \Exception
     */
    public static function create($uid, $skuToken, $acceptId, $messageInfo, $integral, $packetAmount, $couponId, $couponVid, $sCouponInfo, $appType, $mealId = null, $storeId = 0, $isSelfMention = 0, $activityId = 0, $activityType = 0, $teamJoinId = 0)
    {
        $isParagraph = $appType == AppType::APPTYPE_PARAGRAPH_MINIPROGRAM;
        if (!$isParagraph) {
//            throw new \Exception('提交订单失败。好好住商城已升级为「好物」，请更新至最新版本App查看', -1);
        }
        $cacheJson = ConfirmOrderCache::getConfirmInfo($uid, $skuToken);
        toolsLog::order_createOrderData_info('提交订单信息info#date:' . date('YmdHis'), [
            'uid' => $uid,
            'sku_token' => $skuToken,
            'accept_id' => $acceptId,
            'message_info' => $messageInfo,
            'integral' => $integral,
            'packet_amount' => $packetAmount,
            'coupon_id' => $couponId,
            'coupon_vid' => $couponVid,
            's_coupon_info' => $sCouponInfo,
            'app_type' => $appType,
            'meal_id' => $mealId,
            'store_id' => $storeId,
            'self_mention' => $isSelfMention,
            'sku_token_data' => json_decode($cacheJson, true)
        ]);
        if (!$cacheJson) {//订单信息过期或则失效
            toolsLog::order_createOrder_warning('提交订单信息skutoken失效或则过期', [
                'uid' => $uid,
                'sku_token' => $skuToken,
            ]);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_INFO_INVALID], ErrorConst::ERROR_ORDER_INFO_INVALID);
        }
        if (ConfirmOrderCache::dataLock($uid . '-' . $skuToken)) {
            $cacheData = json_decode($cacheJson, true);
            $storeInfo = [];
            if ($storeId) {
                $storeInfo = sStore::admGetStoreInfo($storeId);
            }
            $selfMentionId = ($storeId && $isSelfMention) ? $storeId : 0;
            //获取收货信息
            if ($selfMentionId > 0 && $storeInfo) {
                //姓名：用户昵称，同「买家」字段信息
                //收货地址：自提店铺的店铺地址
                //电话：用户的注册（授权）手机号
                //查询用户昵称和授权手机号
                $mobile = Phone::getDecryptPhoneByUid($uid, findPhoneScene::SHOP_ORDER_PHONE);
                $userInfo = \Doraemon\service\User::getUser($uid);
                $acceptInfo = [
                    'accept_name' => isset($userInfo['nick']) ? $userInfo['nick'] : '',
                    'mobile' => !empty($mobile) ? $mobile : '',
                    'province' => '',
                    'city' => '',
                    'area' => '',
                    'address' => isset($storeInfo['location']) ? $storeInfo['location'] : '',
                    'info_address' => isset($storeInfo['location']) ? $storeInfo['location'] : '',
                    'zipcode' => '',
                ];
            } else {
                $acceptInfo = UserAddressService::getByAcceptId($acceptId);
            }

            //检查收货信息,备注长度,优惠券,积分,红包
            self::checkCreateData($uid, $acceptInfo, $messageInfo, $couponId, $couponVid, $integral, $packetAmount, $selfMentionId);
            $ratioList = [];

            $skuIds = [];
            $skuNumList = [];
            $submitData['accept_info'] = $acceptInfo;
            $submitData['message_info'] = $messageInfo;
            $submitData = $cacheData;
            unset($submitData['list']);
            foreach ($cacheData['list'] as $shopId => $shopOrder) {
                $shopGoodsSecondCategoryIds = [];

                $submitData['list'][$shopId] = $shopOrder;
                unset($submitData['list'][$shopId]['sku_list']);
                foreach ($shopOrder['sku_list'] as $skuInfo) {
                    $submitData['list'][$shopId]['sku_list'][$skuInfo['sku_id']] = $skuInfo;
                    array_push($skuIds, $skuInfo['sku_id']);
                    $skuNumList[$skuInfo['sku_id']] = $skuInfo['buy_num'];

                    $shopGoodsSecondCategoryIds[] = $skuInfo['second_category_id'];
                }
                $shopGoodsSecondCategoryIds = array_unique($shopGoodsSecondCategoryIds);
                //获取店铺佣金比例
                $ratioList[$shopId] = ShopCommissionRate::getShopRatioList($shopId, $shopGoodsSecondCategoryIds);
            }
            $skuInfoList = sSku::Sku4Order($skuIds, ($activityId && $activityType) ? ['activity_id' => $activityId, 'type' => $activityType] : []);
            $computerOrder = new OrderFormat($skuNumList);
            $orderData = $computerOrder->computeConfirmOrder($uid, $skuInfoList, $acceptInfo['city'], false, $sCouponInfo, $couponId, 0, $mealId, $selfMentionId);

            self::checkOrderData($uid, $skuNumList, $submitData, $orderData, $integral, $packetAmount, $couponId, $couponVid, $sCouponInfo, $mealId, $ratioList, $acceptInfo['city'], $selfMentionId);

            $fromSource = self::getOrderFromSource($appType);
            $orderType = self::getOrderType($fromSource, $activityType);
            self::$eventId = Event::genUniqId();
            $orderData['accept_info'] = $acceptInfo;
            $message = [];
            foreach ($messageInfo as $row) {
                $message[$row['shop_id']] = $row['message'];
            }
            $orderData['message'] = $message;
            $orderData['from_source'] = $fromSource;
            $orderData['self_mention_id'] = $selfMentionId;
            $orderResult = self::createOrder($uid, $orderData, $integral, $packetAmount, $ratioList, $appType, $orderType, $teamJoinId, $couponId, $storeInfo, $selfMentionId);
            if ($orderResult && $orderResult['order_parent_no'] && $orderResult['order_parent_info']) {
                toolsLog::order_createOrder_info('创建订单成功', [
                    'uid' => $uid,
                    'order_no' => $orderResult['order_parent_no'],
                    'sku_token' => $skuToken,
                ]);
                ConfirmOrderCache::delConfirmInfo($uid);//清理skutoken
                self::afterCreateOrder($uid, $orderResult, $cacheData['source'], $appType);
                return ['order_no' => $orderResult['order_parent_no']];
            } else {
                toolsLog::order_createOrder_warning('创建订单失败', [
                    'uid' => $uid,
                    'order_result' => $orderResult,
                    'sku_token' => $skuToken,
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }
    }

    private static function checkCreateData($uid, $acceptInfo, $messageInfo, $couponId, $couponVid, $integral, $packetAmount, $selfMentionId)
    {
        //收货信息为空或不完整
        if ($selfMentionId == 0) {
            if (!$acceptInfo || !$acceptInfo['province'] || !$acceptInfo['accept_name'] || !$acceptInfo['mobile'] || !$acceptInfo['address']) {
                toolsLog::order_createOrder_warning('提交订单收货地址为空或则不完整', [
                    'uid' => $uid,
                    'submit_accept_info' => $acceptInfo,
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_ACCEPT_ISNULL], -1);
            }
        }

        foreach ($messageInfo as $row) {
            if (mb_strlen($row['message'], 'utf-8') > 90) {
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_MESSAGE_OUT], -1);
            }
        }

        if ($couponId > 0 && $couponVid > 0) {
            if ($integral) {
                toolsLog::order_createOrder_warning('提交订单优惠券和积分不能同时使用', [
                    'uid' => $uid,
                    'coupon_id' => $couponId,
                    'coupon_vid' => $couponVid,
                    'integral' => $integral,
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }
        if ($packetAmount < 0) {
            toolsLog::order_createOrder_warning('提交订单使用的红包金额不正确', [
                'uid' => $uid,
                'packet_amount' => $packetAmount,
            ]);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
    }

    /**
     * 检查提交订单数据及数据校验
     * @param $uid
     * @param $skuNumList
     * @param array $submitData 提交订单的数据
     * @param array $realData 实时数据库数据
     * @param int $integral
     * @param $packetAmount
     * @param int $couponId
     * @param int $couponVid
     * @param array $sCouponInfo
     * @param int $mealId
     * @param array $ratioList
     * @param $areaCode
     * @param int $selfMentionId
     * @throws \Exception
     */
    private static function checkOrderData($uid, $skuNumList, $submitData, $realData, $integral, $packetAmount, $couponId, $couponVid, $sCouponInfo, $mealId, $ratioList, $areaCode, $selfMentionId = 0)
    {
        if (!$submitData || !$realData || !$submitData['list'] || !$realData['list']) {
            $msg = '提交订单数据异常';
            $errArr = [
                'uid' => $uid,
                'submit_data' => $submitData,
                'real_data' => $realData
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        //检查配送范围,自提不检查配送范围
        if ($selfMentionId <= 0) {
            $supportShipping = true;
            $nonSupportGoods = [];
            foreach ($submitData['support_shipping'] as $shopId => $supportShippingArr) {
                if (!$supportShippingArr['support']) {
                    $supportShipping = false;
                    $nonSupportGoods = array_merge($nonSupportGoods, $supportShippingArr['nonsupport_goods']);
                }
            }
            if ($supportShipping) {
                foreach ($realData['support_shipping'] as $shopId => $supportShippingArr) {
                    if (!$supportShippingArr['support']) {
                        $supportShipping = false;
                        $nonSupportGoods = array_merge($nonSupportGoods, $supportShippingArr['nonsupport_goods']);
                    }
                }
            }
            if (!$supportShipping) {
                $nonSupportGoodsNames = '';
                foreach ($nonSupportGoods as $goodsId) {
                    $nonSupportGoodsNames = '「' . $submitData['goods_titles'][$goodsId] . '」';//只取第一个商品title
                    break;
                }
                $msg = '提交订单收货地址不再配送范围内';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'area_cod' => $areaCode,
                    'submit_support_shipping' => $submitData['support_shipping'],
                    'real_support_shipping' => $realData['support_shipping'],
                    'nosupport_goods' => $nonSupportGoods
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception('抱歉，' . $nonSupportGoodsNames . '无法配送至当前地址', -1);
            }
        }

        //检查商品是否有效 sku库存 购买价格，活动库存和价格
        $realSkuIds = array_keys($realData);
        if (array_diff($submitData['sku_ids'], $realData['sku_ids'])) {//有不存在的sku
            toolsLog::order_createOrder_warning('提交订单skuId和数据库不一致', [
                'uid' => $uid,
                'submit_sku_Ids' => $submitData['sku_ids'],
                'sku_Ids' => $realSkuIds,
            ]);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);
        }

        foreach ($realData['list'] as $shopId => $shopOrder) {
            $submitShopOrder = $submitData['list'][$shopId];
            if (!isset($submitShopOrder)) {
                $msg = '提交订单店铺订单数据不存在';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'submit_data' => $submitData['list'],
                    'real_data' => $realData['list']
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            $shopRationInfo = isset($ratioList[$shopId]) ? $ratioList[$shopId] : null;
            if (!$shopRationInfo) {
                $msg = '提交订单店铺的商品经营类目未开启';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'shop_reation_info' => $shopRationInfo
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            if ($shopOrder['summary']['total_buynum'] != $submitShopOrder['summary']['total_buynum']) {
                $msg = '提交订单店铺购买商品数量不正确';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'total_buynum' => $shopOrder['summary']['total_buynum'],
                    'submit_total_buynum' => $submitShopOrder['summary']['total_buynum'],
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }

            foreach ($shopOrder['sku_list'] as $skuInfo) {
                $skuId = $skuInfo['sku_id'];
                $submitSkuInfo = $submitShopOrder['sku_list'][$skuId];
                //检查sku状态
                if ($skuInfo['status'] != mGoodsSku::STATUS_PASSED) {
                    toolsLog::order_createOrder_warning('提交订单sku状态错误', [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'status' => $skuInfo['status'],
                    ]);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_GOODS_NO_STOCK], ErrorConst::ERROR_GOODS_NO_STOCK);
                }
                //检查商品状态
                if ($skuInfo['goods_status'] != mGoodsSku::STATUS_PASSED) {
                    toolsLog::order_createOrder_warning('提交订单商品状态错误', [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'goods_id' => $skuInfo['goods_id'],
                        'status' => $skuInfo['goods_status'],
                    ]);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_GOODS_NO_STOCK], ErrorConst::ERROR_GOODS_NO_STOCK);
                }
                //检查sku数量
                if ($skuNumList[$skuId] <= 0 || floor($skuNumList[$skuId]) != $skuNumList[$skuId] || $skuNumList[$skuId] != $skuInfo['buy_num']) {
                    $msg = '提交订单sku数量错误';
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'submit_buy_num' => $skuNumList[$skuId],
                        'real_buy_num' => $skuInfo['buy_num'],
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
                //检查sku库存
                if ($skuNumList[$skuId] > $skuInfo['actual_stock']) {
                    $msg = '提交订单sku库存不足';
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'actual_stock' => $skuInfo['actual_stock'],
                        'buy_num' => $skuNumList[$skuId],
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);//库存不足
                }
                //检查sku价格
                if ($submitSkuInfo['actual_price'] != $skuInfo['actual_price']) {//商品价格变化
                    $msg = '提交订单sku价格变化';
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'actual_price' => $skuInfo['actual_price'],
                        'submit_actual_price' => $submitSkuInfo['actual_price'],
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_GOODS_PRICE_CHANGE], ErrorConst::ERROR_GOODS_PRICE_CHANGE);
                };
                //检查sku活动
                $activityId = (isset($skuInfo['activity_id']) && $skuInfo['activity_id']) ? $skuInfo['activity_id'] : null;
                $activityType = (isset($skuInfo['activity_type']) && $skuInfo['activity_type']) ? $skuInfo['activity_type'] : null;
                $submitActivityId = (isset($submitSkuInfo['activity_id']) && $submitSkuInfo['activity_id']) ? $submitSkuInfo['activity_id'] : null;
                $submitActivityType = (isset($submitSkuInfo['activity_type']) && $submitSkuInfo['activity_type']) ? $submitSkuInfo['activity_type'] : null;
                if (!is_null($submitActivityId) && !is_null($submitActivityType) && ($submitActivityType != $activityType || $submitActivityId != $activityId)) {
                    $msg = '提交订单sku活动不存在或则已经结束';
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'activity_id' => $activityId,
                        'activity_type' => $activityType,
                        'submit_activity_id' => $submitActivityId,
                        'submit_activity_type' => $submitActivityType,
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);
                };

                //检查sku平台活动补贴
                if ($skuInfo['activity_allowance'] != $submitSkuInfo['activity_allowance']) {
                    $msg = '提交订单sku商品的平台活动补贴不正确';
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $skuId,
                        'submit_activity_allowance' => $submitSkuInfo['activity_allowance'],
                        'activity_allowance' => $skuInfo['activity_allowance'],
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }

                //检查店铺开启的经营类目
                $secondCategoryId = isset($skuInfo['second_category_id']) ? $skuInfo['second_category_id'] : null;
                if (!$secondCategoryId || !isset($shopRationInfo[$secondCategoryId]) || !$shopRationInfo[$secondCategoryId] || !$shopRationInfo[$secondCategoryId]['status']) {
                    $msg = '提交订单商品的经营类目未开启';
                    $errArr = [
                        'uid' => $uid,
                        'goods_Id' => $skuInfo['goods_id'],
                        'category_id' => $skuInfo['category_id'],
                        'second_category_id' => $secondCategoryId,
                        'shop_id' => $shopId,
                    ];
                    toolsLog::order_createOrder_warning($msg, $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
            }

            //检查店铺优惠券
            $sCouponErr = false;
            $shopCouponData = $shopOrder['coupon'];
            $submitShopCouponData = $submitShopOrder['coupon'];
            if ($sCouponInfo[$shopId] && $sCouponInfo[$shopId]['coupon_id'] > 0 && $sCouponInfo[$shopId]['coupon_vid'] > 0) {
                if ($submitShopCouponData && $shopCouponData && $submitShopCouponData['coupon_id'] > 0 && $shopCouponData['coupon_id'] > 0 && $submitShopCouponData['coupon_vid'] > 0 && $shopCouponData['coupon_vid'] > 0) {
                    if ($submitShopCouponData['coupon']['coupon_id'] != $shopCouponData['coupon']['coupon_id']) {
                        $sCouponErr = true;
                    }
                    if ($submitShopCouponData['coupon_vid'] != $shopCouponData['coupon_vid']) {
                        $sCouponErr = true;
                    }
                    if ($submitShopCouponData['detract_amount'] != $shopCouponData['detract_amount']) {
                        $sCouponErr = true;
                    }
                } else {
                    $sCouponErr = true;
                }
            } else {
                if (isset($submitShopCouponData['coupon_id']) && $submitShopCouponData['coupon_id'] > 0) {
                    $sCouponErr = true;
                }
                if (isset($submitShopCouponData['coupon_vid']) && $submitShopCouponData['coupon_vid'] > 0) {
                    $sCouponErr = true;
                }
                if (isset($shopCouponData['coupon_id']) && $shopCouponData['coupon_id'] > 0) {
                    $sCouponErr = true;
                }
                if (isset($shopCouponData['coupon_vid']) && $shopCouponData['coupon_vid'] > 0) {
                    $sCouponErr = true;
                }
            }
            if ($sCouponErr) {
                $msg = '提交订单使用店铺优惠券数据异常';
                $errArr = [
                    'uid' => $uid,
                    's_coupon_info' => $sCouponInfo,
                    'submit_s_coupon' => $submitData['coupon'],
                    'real_s_coupon' => $realData['coupon'],
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            //检查套餐
            $mealErr = false;
            $mealInfo = $shopOrder['meal'];
            $submitMealInfo = $submitShopOrder['meal'];
            if ($mealId) {
                if ($mealInfo['meal_id'] && $submitMealInfo['meal_id']) {
                    if ($mealInfo['meal_id'] != $submitMealInfo['meal_id'] || $mealInfo['meal_id'] != $mealId || $submitMealInfo['meal_id'] != $mealId) {
                        $mealErr = true;
                    }
                    if ($mealInfo['detract_amount'] != $mealInfo['detract_amount']) {
                        $mealErr = true;
                    }
                } else {
                    $mealErr = true;
                }
            } else {
                if (isset($mealInfo['meal_id']) || $mealInfo['meal_id']) {
                    $mealErr = true;
                }
                if (isset($submitMealInfo['meal_id']) || $submitMealInfo['meal_id']) {
                    $mealErr = true;
                }
            }
            if ($mealErr) {
                $msg = '提交订单店铺套餐数据异常';
                $errArr = [
                    'uid' => $uid,
                    'meal_id' => $mealId,
                    'meal_info' => $mealInfo,
                    'submit_meal_info' => $submitMealInfo,
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }

            if ($shopOrder['summary']['goods_amount'] != $submitShopOrder['summary']['goods_amount']) {
                $msg = '提交订单店铺商品总额不正确';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'goods_amount' => $shopOrder['summary']['goods_amount'],
                    'submit_goods_amount' => $submitShopOrder['summary']['goods_amount'],
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            if ($shopOrder['summary']['shipping_amount'] != $submitShopOrder['summary']['shipping_amount']) {
                $msg = '提交订单店铺运费不正确';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'shipping_amount' => $shopOrder['summary']['shipping_amount'],
                    'submit_shipping_amount' => $submitShopOrder['summary']['shipping_amount'],
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            if ($shopOrder['summary']['total_amount'] != $submitShopOrder['summary']['total_amount']) {
                $msg = '提交订单店铺小计不正确';
                $errArr = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'total_amount' => $shopOrder['summary']['total_amount'],
                    'submit_total_amount' => $submitShopOrder['summary']['total_amount'],
                ];
                toolsLog::order_createOrder_warning($msg, $errArr);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }

        //校验优惠券
        $couponErr = false;
        if ($couponId > 0 && $couponVid > 0) {
            if ($submitData['coupon'] && $realData['coupon'] && $submitData['coupon']['coupon_id'] > 0 && $realData['coupon']['coupon_id'] > 0 && $submitData['coupon']['coupon_vid'] > 0 && $realData['coupon']['coupon_vid'] > 0) {
                if ($submitData['coupon']['coupon_id'] != $realData['coupon']['coupon_id']) {
                    $couponErr = true;
                }
                if ($submitData['coupon']['coupon_vid'] != $realData['coupon']['coupon_vid']) {
                    $couponErr = true;
                }
                if ($submitData['coupon']['detract_amount'] != $realData['coupon']['detract_amount']) {
                    $couponErr = true;
                }
            } else {
                $couponErr = true;
            }
        } else {
            if (isset($submitData['coupon']['coupon_id']) && $submitData['coupon']['coupon_id'] > 0) {
                $couponErr = true;
            }
            if (isset($submitData['coupon']['coupon_vid']) && $submitData['coupon']['coupon_vid'] > 0) {
                $couponErr = true;
            }
            if (isset($realData['coupon']['coupon_id']) && $realData['coupon']['coupon_id'] > 0) {
                $couponErr = true;
            }
            if (isset($realData['coupon']['coupon_vid']) && $realData['coupon']['coupon_vid'] > 0) {
                $couponErr = true;
            }
        }
        if ($couponErr) {
            $msg = '提交订单使用平台券数据异常';
            $errArr = [
                'uid' => $uid,
                'coupon_id' => $couponId,
                'coupon_vid' => $couponVid,
                'submit_coupon' => $submitData['coupon'],
                'real_coupon' => $realData['coupon'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }

        //校验积分比例
        $integralErr = false;
        if ($integral) {
            if ($realData['integral']) {
                if ($submitData['integral']) {
                    if ($realData['integral']['discount'] > 0 && $realData['integral']['discount'] != $submitData['integral']['discount']) {
                        $integralErr = true;
                    }
                    if ($integral != $realData['integral']['usable'] || $integral != $submitData['integral']['usable']) {
                        $integralErr = true;
                    }
                } else {
                    $integralErr = true;
                }
            } else {
                if ($submitData['integral']) {
                    $integralErr = true;
                }
            }
        }
        if ($integralErr) {
            $msg = '提交订单使用积分数据异常';
            $errArr = [
                'uid' => $uid,
                'submit_integral' => $integral,
                'submit_integral_info' => $submitData['integral'],
                'real_integral_info' => $realData['integral'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }

        //检验红包
        $packetErr = false;
        if ($packetAmount > 0) {
            if ($realData['red_packet']) {
                if ($submitData['red_packet']) {
                    if ($realData['red_packet']['packet_amount'] > 0 && $realData['red_packet']['packet_amount'] != $submitData['red_packet']['packet_amount']) {
                        $packetErr = true;
                    }
                    if ($packetAmount != $realData['red_packet']['packet_amount'] || $packetAmount != $submitData['red_packet']['packet_amount']) {
                        $packetErr = true;
                    }
                } else {
                    $packetErr = true;
                }
            } else {
                if ($submitData['$packetErr']) {
                    $packetErr = true;
                }
            }
        }
        if ($packetErr) {
            $msg = '提交订单使用红包数据异常';
            $errArr = [
                'uid' => $uid,
                'submit_packet_amount' => $packetAmount,
                'submit_red_packet' => $submitData['red_packet'],
                'real_red_packet' => $realData['red_packet'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }

        //校验 订单总额
        if (bccomp($realData['summary']['total_buynum'], $submitData['summary']['total_buynum'], 2) != 0) {
            $msg = '提交订单商品购买总数不正确';
            $errArr = [
                'uid' => $uid,
                'total_buynum' => $realData['summary']['total_buynum'],
                'submit_total_buynum' => $submitData['summary']['total_buynum'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        if (bccomp($realData['summary']['goods_amount'], $submitData['summary']['goods_amount'], 2) != 0) {
            $msg = '提交订单商品总额不正确';
            $errArr = [
                'uid' => $uid,
                'goods_amount' => $realData['summary']['goods_amount'],
                'submit_goods_amount' => $submitData['summary']['goods_amount'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        if (bccomp($realData['summary']['shipping_amount'], $submitData['summary']['shipping_amount'], 2) != 0) {
            $msg = '提交订单总运费不正确';
            $errArr = [
                'uid' => $uid,
                'shipping_amount' => $realData['summary']['shipping_amount'],
                'submit_shipping_amount' => $submitData['summary']['shipping_amount'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        if (bccomp($realData['summary']['total_amount'], $submitData['summary']['total_amount'], 2) != 0) {
            $msg = '提交订单总额不正确';
            $errArr = [
                'uid' => $uid,
                'total_amount' => $realData['summary']['total_amount'],
                'submit_total_amount' => $submitData['summary']['total_amount'],
            ];
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
    }


    /**
     * 生成订单
     * @param $uid
     * @param $orderData 订单数据
     * @param $integral 用户使用的积分
     * @param $packetAmount 用户使用的现金红包
     * @param $ratioList 佣金数据
     * @param $appType app来源
     * @param int $orderType 订单类型（0:app 1:团购订单）
     * @param int $teamJoinId
     * @param int $couponId
     * @param array $storeInfo 节选店铺info
     * @param int $selfMentionId 自提店铺id
     * @return bool
     * @throws \Exception
     */
    private static function createOrder($uid, $orderData, $integral, $packetAmount, $ratioList, $appType, $orderType = mOrder::ORDER_TYPE_NORMAL, $teamJoinId = 0, $couponId = 0, $storeInfo = [], $selfMentionId = 0)
    {
        $isDesigner = false;
        $designerPhone = '';
        if ($appType == AppType::APPTYPE_PARAGRAPH_MINIPROGRAM) {//如果是节选订单，
            $abbr = '';
            if ($couponId > 0) {//使用了节选优惠券
                $areaCoupon = sSalesRebate::getCouponInfo($couponId);
                if (!$areaCoupon) {
                    $errArr = [
                        'uid' => $uid,
                        'coupon_id' => $couponId,
                        'area_coupon' => $areaCoupon,
                    ];
                    $msg = '提交节选订单获取节选优惠券所属地区失败';
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    toolsLog::order_createOrder_warning($msg, json_encode($errArr, JSON_UNESCAPED_UNICODE));
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
                if ($areaCoupon) {
                    $abbr = $areaCoupon['area'];
                    $isDesigner = $areaCoupon['is_designer'];
                    $designerPhone = $areaCoupon['phone'];
                    if ($isDesigner && !$designerPhone) {
                        $errArr = [
                            'coupon_id' => $couponId,
                            'area_coupon' => $areaCoupon,
                            'uid' => $uid,
                        ];
                        $msg = '提交节选订单获取节选设计师手机号失败';
                        Queue::insertQueue("queue/Wechatnotice/toTag", [
                            "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                            "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                        ], Queue::QUEUE_BIZ);
                        toolsLog::order_createOrder_warning($msg, json_encode($errArr, JSON_UNESCAPED_UNICODE));
                        throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                    }
                    if (!$selfMentionId) {
                        $storeInfo = [];
                    }
                }
                //订单归属规则：选择自提店铺权重>优惠码地区权重 >选择光临过的店铺权重
                if ($storeInfo && $selfMentionId && $abbr) {//若出现「提货店铺城市」与「优惠码归属地」不一致的情况，以「提货店铺城市」为第一优先级——订单归属地以提货城市为准
                    if ($storeInfo['abbr'] != $abbr) {
                        $isDesigner = false;
                        $designerPhone = '';
                    }
                }
            }
            if (!$storeInfo) {
                if (empty($abbr)) {
                    $provinceCode = strval($orderData['accept_info']['province']);
                    $abbr = TheParagraphStore::STORE_SH;
                    // if ($provinceCode && isset(TheParagraphStore::STORE_AREA_CODE_BJ[$provinceCode])) {
                    //     $abbr = TheParagraphStore::STORE_BJ;
                    // } else if ($provinceCode && isset(TheParagraphStore::STORE_AREA_CODE_SH[$provinceCode])) {
                    //     $abbr = TheParagraphStore::STORE_SH;
                    // }
                }
                if ($abbr) {
                    $storeInfo = sStore::getStoreByAbbr($abbr);
                }
            }
            if (!$storeInfo) {
                $errArr = [
                    'coupon_id' => $couponId,
                    'store_info' => $storeInfo,
                    'abbr' => $abbr,
                ];
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => "提交节选订单获取订单店铺失败:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                toolsLog::order_createOrder_warning('提交节选订单获取订单店铺失败', json_encode($errArr, JSON_UNESCAPED_UNICODE));
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }
        $shopIds = array_keys($orderData['list']);
        $orderNOs = toolOrderNo::genNo($uid, $shopIds, $appType, $orderType, $storeInfo ? $storeInfo['abbr'] : '');
        if (!$orderNOs || !$orderNOs['P']) {//生成订单号失败
            toolsLog::order_createOrder_warning('提交订单生成订单号失败', [
                'uid' => $uid,
                'shop_ids' => $shopIds,
            ]);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        $orderPno = $orderNOs['P'];
        $totalAmount = $orderData['summary']['total_amount'];

        //使用优惠券，平均计算到sku
        $couponId = (isset($orderData['coupon']) && isset($orderData['coupon']['coupon_id'])) ? $orderData['coupon']['coupon_id'] : 0;
        $couponVid = (isset($orderData['coupon']) && isset($orderData['coupon']['coupon_vid'])) ? $orderData['coupon']['coupon_vid'] : 0;
        $couponAmount = (isset($orderData['coupon']) && isset($orderData['coupon']['detract_amount'])) ? $orderData['coupon']['detract_amount'] : 0;

        $skuCouponDiscount = $orderData['coupon_sku'];

        //使用的积分，平均计算到sku
        $integralData = [];
        $integralInfo = [];
        if ($integral > 0) {
            $integralData = $orderData['integral_sku'];
            $integralInfo = $orderData['integral'];
        }
        $canUseIntegral = [];
        $useIntegral = 0;
        $useIntegrealAmount = 0;

        if (!$skuCouponDiscount) {//优惠券和积分不能同时使用
            if ($integralInfo && $integralData && is_array($integralData)) {
                $canUseIntegral = $integralData;
                $useIntegral = $canUseIntegral['sum'];
                $useIntegrealAmount = number_format($canUseIntegral['discount'], 2);
            }
        }

        //使用红包
        $redPacketData = [];
        $redPacketSku = [];
        $useRedPacketAmount = 0;
        if ($packetAmount > 0) {
            $redPacketData = $orderData['red_packet_sku'];
            $redPacketSku = $redPacketData ? $redPacketData['data'] : [];
            $useRedPacketAmount = $redPacketData ? $redPacketData['discount'] : 0;
        }

        $now = time();
        $payStopTime = $now + mOrder::MAX_WAIT_PAY_TIME;
        $discountAmount = 0;
        $shopAllCouponAmount = 0;
        $shopAllMealAmount = 0;
        $allOrderActivityAllowance = 0;
        $payAllAmount = 0;
        $payAllAmount = bcadd($payAllAmount, $useIntegrealAmount, 2);
        $payAllAmount = bcadd($payAllAmount, $useRedPacketAmount, 2);
        $payAllAmount = bcadd($payAllAmount, $discountAmount, 2);
        $payAllAmount = bcadd($payAllAmount, $couponAmount, 2);
        $payAllAmount = bcsub($totalAmount, $payAllAmount, 2);
        $orderParentInsert = [
            'order_parent_no' => $orderPno,
            'uid' => $uid,
            'order_type' => $orderType,
            'goods_amount' => $orderData['summary']['goods_amount'],
            'shipping' => $orderData['summary']['shipping_amount'],
            'discount_amount' => $discountAmount,
            'integral' => $useIntegral,
            'integral_amount' => number_format($useIntegral / sIntegral::CONVERSION_RATIO, 2),
            'packet_amount' => $useRedPacketAmount,
            'coupon_vid' => $couponVid ? $couponVid : 0,
            'coupon_id' => $couponId ? $couponId : 0,
            'coupon_amount' => $couponAmount ? $couponAmount : 0,
            'activity_allowance' => 0,
            'sum_s_coupon_amount' => 0,
            'sum_s_meal_amount' => 0,
            'buy_num' => $orderData['summary']['total_buynum'],
            'pay_amount' => $payAllAmount,
            'addtime' => date('Y-m-d H:i:s', $now),
            'paystop_time' => date('Y-m-d H:i:s', $payStopTime),//支付最终时间
        ];

        $orderInsert = [];
        $orderPackage = [];
        $orderExtendInsert = [];
        $orderGoodsInsert = [];
        $groupInsert = [];

        $buySkuList = [];
        $shopIntegralArr = [];
        $shopCouponList = [];
        $shopRedPacketArr = [];
        foreach ($orderData['list'] as $shopId => &$list) {

            if ($orderType == mOrder::ORDER_TYPE_PING_TUAN) {
                $groupInsert = ['uid' => $uid, 'sku_id' => $orderData['sku_ids'][0], 'team_join_id' => $teamJoinId, 'order_no' => $orderNOs[$shopId]];
            }

            $list['order_no'] = $orderNOs[$shopId];
            $shopIntegral = ($canUseIntegral && isset($canUseIntegral['data'][$shopId]['sum'])) ? $canUseIntegral['data'][$shopId]['sum'] : 0;
            $shopIntegralAmount = number_format($shopIntegral / sIntegral::CONVERSION_RATIO, 2);
            $shopIntegralArr[] = ['order_no' => $orderNOs[$shopId], 'integral' => $shopIntegral];
            $list['integral_amount'] = $shopIntegralAmount;
            $shopDiscountAmount = 0;
            $list['discount_amount'] = $shopDiscountAmount;

            $skuShopCouponDiscount = [];
            $shopCouponInfo = [];
            if (isset($list['coupon']) && $list['coupon']['coupon_id'] > 0) {
                $skuShopCouponDiscount = $list['coupon_sku'];
                $shopCouponInfo = $list['coupon'];
                $shopCouponList[$shopId] = $shopCouponInfo;
                $shopCouponList[$shopId]['order_no'] = $orderNOs[$shopId];
            }


            $mealGoodsPrice = [];
            $mealId = 0;
            if (isset($list['meal']) && $list['meal']['meal_id'] > 0) {
                $mealId = $list['meal']['meal_id'];
                $mealGoodsPrice = $list['meal_sku'];
            }
            $payAmount = 0;
            $payAmount = bcadd($shopIntegralAmount, $shopDiscountAmount, 2);
            $payAmount = bcsub($orderData['list'][$shopId]['summary']['total_amount'], $payAmount, 2);
            $orderInsert[$shopId] = [
                'order_no' => $orderNOs[$shopId],
                'uid' => $uid,
                'shop_id' => $shopId,
                'order_parent_no' => $orderPno,
                'order_type' => $orderType,
                'integral' => $shopIntegral,
                'integral_amount' => $shopIntegralAmount,
                'packet_amount' => 0,
                'coupon_vid' => $couponVid ? $couponVid : 0,
                'coupon_id' => $couponId ? $couponId : 0,
                'coupon_amount' => 0,
                'activity_allowance' => 0,
                's_coupon_vid' => $shopCouponInfo ? $shopCouponInfo['coupon_vid'] : 0,
                's_coupon_id' => $shopCouponInfo ? $shopCouponInfo['coupon_id'] : 0,
                's_coupon_amount' => 0,
                'meal_id' => $mealId,
                'meal_amount' => 0,
                'goods_amount' => $orderData['list'][$shopId]['summary']['goods_amount'],
                'discount_amount' => $shopDiscountAmount,
                'full_shipping_plan_id' => $orderData['list'][$shopId]['summary']['full_shipping_plan_id'],
                'shipping_fee' => $orderData['list'][$shopId]['summary']['shipping_fee'],
                'shipping_amount' => $orderData['list'][$shopId]['summary']['shipping_amount'],
                'buy_num' => $orderData['list'][$shopId]['summary']['total_buynum'],
                'address_id' => isset($orderData['accept_info']['id']) ? $orderData['accept_info']['id'] : 0,
                'consignee_name' => $orderData['accept_info']['accept_name'],
                'consignee_phone' => $orderData['accept_info']['mobile'],
                'consignee_province' => $orderData['accept_info']['province'],
                'consignee_city' => $orderData['accept_info']['city'],
                'consignee_area' => $orderData['accept_info']['area'],
                'consignee_address' => $orderData['accept_info']['address'],
                'consignee_info_address' => $orderData['accept_info']['info_address'],
                'consignee_zipcode' => $orderData['accept_info']['zipcode'],
                'pay_amount' => $payAmount,
                'status' => mOrder::STATUS_NORMAL,
                'message' => isset($orderData['message'][$shopId]) ? $orderData['message'][$shopId] : '',
                'addtime' => date('Y-m-d H:i:s', $now),
                'paystop_time' => date('Y-m-d H:i:s', $payStopTime),//支付最终时间
                'from_source' => $orderData['from_source'],
            ];
            //节选门店自提
            if ($orderData['self_mention_id'] > 0) {
                $orderPackage[$shopId] = [
                    'order_no' => $orderNOs[$shopId],
                    'express_company' => '门店自提',
                    'express_no' => $orderData['self_mention_id'],
                    'sku_id_list' => [],
                ];
            }

            $orderExtendInsert[$shopId] = [
                'order_no' => $orderNOs[$shopId],
                'store_id' => $storeInfo ? $storeInfo['id'] : 0,
                'is_designer' => $isDesigner,
                'designer_phone' => $designerPhone,
            ];

            $orderCommissions = 0;
            $orderCouponAmount = 0;
            $orderShopCouponAmount = 0;
            $orderMealAmount = 0;
            $orderActivityAllowance = 0;
            $orderShopRedPacketAmount = 0;
            foreach ($list['sku_list'] as $skuInfo) {
                $skuId = $skuInfo['sku_id'];

                $shippingTemplId = 0;
                $shippingAmount = 0;
                if (isset($orderData['sku_shipping_amount'][$shopId]) && isset($orderData['sku_shipping_amount'][$shopId][$skuId])) {
                    $shippingTemplId = $orderData['sku_shipping_amount'][$shopId][$skuId]['shipping_templ_id'];
                    $shippingAmount = $orderData['sku_shipping_amount'][$shopId][$skuId]['price'];
                }

                //如果包裹里有值，那么则需要补充包裹的skuid，目前只有节选自提里有
                if (!empty($orderPackage[$shopId])) {
                    $orderPackage[$shopId]['sku_id_list'][] = $skuId;
                }

                $skuIntegral = ($canUseIntegral && isset($canUseIntegral['data'][$shopId]['list'][$skuId])) ? $canUseIntegral['data'][$shopId]['list'][$skuId] : 0;
                $skuIntegralAmount = number_format($skuIntegral / sIntegral::CONVERSION_RATIO, 2);
                $promoType = $skuInfo['activity_type'] ? $skuInfo['activity_type'] : 0;
                $promoId = $skuInfo['activity_id'] ? $skuInfo['activity_id'] : 0;
                $categoryRatioInfo = $ratioList[$shopId][$skuInfo['second_category_id']];
                $ratio = self::getCategoryRatio($categoryRatioInfo['ratio'], $storeInfo ? $storeInfo['abbr'] : '', $isDesigner, $categoryRatioInfo['ratio_ext']);
                $categoryId = $skuInfo['category_id'];
                $secondCategoryId = $skuInfo['second_category_id'];
                $goodsRatio = self::getGoodsRatio($skuInfo['ratio'], $storeInfo ? $storeInfo['abbr'] : '', $isDesigner, $skuInfo['ratio_ext']);
                if (!is_null($goodsRatio) && $goodsRatio >= 0) {
                    $ratio = $goodsRatio;
                }
                $skuDiscountAmount = 0;

                $skuCouponId = 0;
                $skuCouponVId = 0;
                $skuCouponAmount = 0;
                if (isset($skuCouponDiscount[$skuId]['coupon_discount'])) {
                    $skuCouponAmount = $skuCouponDiscount[$skuId]['coupon_discount'];
                    $skuCouponId = $couponId;
                    $skuCouponVId = $couponVid;
                }
                $orderCouponAmount = bcadd($orderCouponAmount, $skuCouponAmount, 2);

                $skuShopCouponAmount = isset($skuShopCouponDiscount[$skuId]['coupon_discount']) ? $skuShopCouponDiscount[$skuId]['coupon_discount'] : 0;
                $orderShopCouponAmount = bcadd($orderShopCouponAmount, $skuShopCouponAmount, 2);
                $shopAllCouponAmount = bcadd($shopAllCouponAmount, $skuShopCouponAmount, 2);

                $skuShopMealAmount = isset($mealGoodsPrice['sku_price'][$skuId]['detract_price']) ? $mealGoodsPrice['sku_price'][$skuId]['detract_price'] : 0;
                $orderMealAmount = bcadd($orderMealAmount, $skuShopMealAmount, 2);
                $shopAllMealAmount = bcadd($shopAllMealAmount, $skuShopMealAmount, 2);

                $skuRedPacketAmount = isset($redPacketSku[$skuId]) ? $redPacketSku[$skuId] : 0;
                $orderShopRedPacketAmount = bcadd($orderShopRedPacketAmount, $skuRedPacketAmount, 2);


                $activityAllowance = $skuInfo['activity_allowance'] * $skuInfo['buy_num'];
                $commissionAmount = $skuInfo['actual_price'] * $skuInfo['buy_num'];
                $commissionAmount = bcadd($commissionAmount, $activityAllowance, 2);
                $commissionAmount = bcsub($commissionAmount, $skuShopCouponAmount, 2);
                $commissionAmount = bcsub($commissionAmount, $skuShopMealAmount, 2);
                $commissions = $commissionAmount * ($ratio / 100);
                $commissions = round($commissions, 2);
                $orderCommissions = bcadd($orderCommissions, $commissions, 2);
                $orderActivityAllowance = bcadd($orderActivityAllowance, $activityAllowance, 2);
                $allOrderActivityAllowance = bcadd($allOrderActivityAllowance, $activityAllowance, 2);

                if (strtotime($skuInfo['forecast_ship_time']) > $now) {
                    $shippingTime = $skuInfo['forecast_ship_time'];
                } else if ($skuInfo['shipping_info']['shipping_time_hour']) {
                    $shippingTime = $skuInfo['shipping_info']['shipping_time_hour'] * 3600 + $now;
                    $shippingTime = date('Y-m-d H:i:s', $shippingTime);
                } else {
                    $shippingTime = '1970-01-01 12:00:00';
                }
                $orderGoodsInsert[$skuId] = [
                    'uid' => $uid,
                    'shop_id' => $shopId,
                    'order_no' => $orderNOs[$shopId],
                    'order_type' => $orderType,
                    'goods_id' => $skuInfo['goods_id'],
                    'sku_id' => $skuId,
                    'category_id' => $categoryId,
                    'second_category_id' => $secondCategoryId,
                    'title' => $skuInfo['title'],
                    'cover_img' => $skuInfo['spec_img'],
                    'sku_desc' => $skuInfo['sku_desc'],
                    'sell_price' => $skuInfo['ori_price'],
                    'buy_price' => $skuInfo['actual_price'],
                    'buy_num' => $skuInfo['buy_num'],
                    'goods_amount' => $skuInfo['actual_price'] * $skuInfo['buy_num'],
                    'shipping_templ_id' => $shippingTemplId,
                    'shipping_amount' => $shippingAmount,
                    'integral' => $skuIntegral,
                    'integral_amount' => $skuIntegralAmount,
                    'packet_amount' => $skuRedPacketAmount,
                    'coupon_vid' => $skuCouponVId,
                    'coupon_id' => $skuCouponId,
                    'coupon_amount' => $skuCouponAmount,
                    'activity_allowance' => $activityAllowance,
                    's_coupon_vid' => $shopCouponInfo ? $shopCouponInfo['coupon_vid'] : 0,
                    's_coupon_id' => $shopCouponInfo ? $shopCouponInfo['coupon_id'] : 0,
                    's_coupon_amount' => $skuShopCouponAmount,
                    'meal_id' => $mealId,
                    'meal_amount' => $skuShopMealAmount,
                    'discount_amount' => $skuDiscountAmount,
                    'pay_amount' => $skuInfo['actual_price'] * $skuInfo['buy_num'] - $skuIntegralAmount - $skuCouponAmount - $skuDiscountAmount - $skuShopCouponAmount - $skuShopMealAmount - $skuRedPacketAmount,
                    'commission_rate' => $ratio,
                    'commissions' => $commissions,
                    'promo_type' => $promoType,
                    'promo_id' => $promoId,
                    'addtime' => date('Y-m-d H:i:s', $now),
                    'shipping_time' => $shippingTime
                ];
                $buySkuList[$orderNOs[$shopId]][] = [
                    "goods_id" => $skuInfo['goods_id'],
                    "sku_id" => $skuId,
                    "buy_num" => $skuInfo['buy_num'],
                    'promo_type' => $promoType,
                    'promo_id' => $promoId
                ];
            }
            $orderInsert[$shopId]['activity_allowance'] = $orderActivityAllowance;
            $orderInsert[$shopId]['commissions'] = $orderCommissions;
            $orderInsert[$shopId]['coupon_amount'] = $orderCouponAmount;
            $orderInsert[$shopId]['pay_amount'] = bcsub($orderInsert[$shopId]['pay_amount'], $orderCouponAmount, 2);
            $orderInsert[$shopId]['s_coupon_amount'] = $orderShopCouponAmount;
            $orderInsert[$shopId]['meal_amount'] = $orderMealAmount;
            $orderInsert[$shopId]['packet_amount'] = $orderShopRedPacketAmount;
            $orderInsert[$shopId]['pay_amount'] = bcsub($orderInsert[$shopId]['pay_amount'], $orderShopRedPacketAmount, 2);

            $shopRedPacketArr[] = ['order_no' => $orderNOs[$shopId], 'packet_amount' => $orderShopRedPacketAmount];
        }
        $orderParentInsert['activity_allowance'] = $allOrderActivityAllowance;
        $orderParentInsert['sum_s_coupon_amount'] = $shopAllCouponAmount;
        $orderParentInsert['sum_s_meal_amount'] = $shopAllMealAmount;
        if (!$orderParentInsert['pay_amount']) {//0元订单
            $errArr = [
                'order_parent_info' => $orderParentInsert,
            ];
            toolsLog::order_createOrder_warning('提交订单失败，订单支付金额小于或则等于0', $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "提交订单失败，订单支付金额小于或则等于0:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }
        //var_dump($orderParentInsert,$orderInsert,$orderGoodsInsert);

        //检查入库数据
        self::checkInsertOrderData($uid, $orderParentInsert, $orderInsert, $orderGoodsInsert);

        if ($orderType != mOrder::ORDER_TYPE_PING_TUAN) {//拼团订单成团后才扣库存
            //减库存
            $orders = $orderNOs;
            unset($orders['P']);
            $decrStockResult = sStock::DecrStockByOrderNo($orderPno, $buySkuList);
            if (!$decrStockResult) {
                toolsLog::order_createOrder_warning('提交订单减库存失败', [
                    'order_parent_no' => $orderPno,
                    'uid' => $uid,
                    'data' => $buySkuList,
                ]);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => "提交订单减库存失败:" . "#params:" . json_encode([
                            'order_parent_no' => $orderPno,
                            'uid' => $uid,
                            'data' => $buySkuList,
                        ], JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }

        //使用店铺优惠券
        if ($shopCouponList) {
            foreach ($shopCouponList as $shopId => $shopCouponInfo) {
                $useShopCoupon = clsShopCoupon::useAShopCouponInOrder($uid, $shopId, $shopCouponInfo['order_no'], $shopCouponInfo['coupon_vid'], $shopCouponInfo['coupon_id']);
                if (!$useShopCoupon) {
                    toolsLog::order_createOrder_warning('提交订单使用店铺优惠券失败', [
                        'result' => $useShopCoupon,
                        'uid' => $uid,
                        'data' => [
                            'shop_id' => $shopId,
                            'coupon_id' => $shopCouponInfo['coupon_id'],
                            'coupon_vid' => $shopCouponInfo['coupon_vid'],
                            'order_no' => $shopCouponInfo['order_no']
                        ],
                    ]);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
            }
        }

        //使用平台优惠券
        if ($couponId > 0 && $couponVid > 0) {
            $useCoupon = clsCoupon::useACouponInOrder($uid, $orderPno, $couponVid, $couponId);
            if (!$useCoupon) {
                toolsLog::order_createOrder_warning('提交订单使用优惠券失败', [
                    'result' => $useCoupon,
                    'uid' => $uid,
                    'data' => [
                        'coupon_id' => $couponId,
                        'coupon_vid' => $couponVid,
                        'order_parent_no' => $orderPno
                    ],
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        }
        //减积分
        foreach ($shopIntegralArr as $row) {
            sIntegral::operatePoint($uid, $row['integral'], $row['order_no'], 1);
        }

        //使用红包
        foreach ($shopRedPacketArr as $row) {
            if ($row['packet_amount'] > 0) {
                sRedPackets::useInOrder($uid, $row['order_no'], $row['packet_amount']);
            }
        }

        //创建拼团信息
        if ($orderType == mOrder::ORDER_TYPE_PING_TUAN) {
            if ($groupInsert) {
                try {
                    sGroup::createGroup($groupInsert['uid'], $groupInsert['sku_id'], $groupInsert['order_no'], $groupInsert['team_join_id']);
                } catch (\Exception $e) {
                    $msg = $e->getMessage();
                    $errArr = [
                        'uid' => $uid,
                        'sku_id' => $groupInsert['sku_id'],
                        'order_no' => $groupInsert['order_no'],
                        'team_join_id' => $groupInsert['team_join_id']
                    ];
                    toolsLog::order_createOrder_warning('提交订单创建开团信息失败#' . $msg . '#file' . $e->getFile() . '#line' . $e->getLine(), $errArr);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
            }
        }

        //创建订单数据
        $result = mOrderParent::action(function () use ($uid, $orderPno, $orderParentInsert, $orderInsert, $orderPackage, $orderExtendInsert, $orderGoodsInsert) {
            //写入订单数据
            if ($orderParentInsert && $orderInsert && $orderGoodsInsert) {
                $result = mOrderParent::insertParentOrder($orderParentInsert);
                if (!$result) {//创建订单数据失败
                    $errArr = [
                        'result' => $result,
                        'sql' => mOrderParent::log(),
                        'data' => $orderParentInsert,
                    ];
                    toolsLog::order_createOrder_warning('提交订单创建主订单数据失败', $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => "提交订单创建主订单数据失败:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
                $result = mOrder::insertOrder(array_values($orderInsert));
                if (!$result) {
                    $errArr = [
                        'result' => $result,
                        'sql' => mOrder::log(),
                        'data' => $orderInsert,
                    ];
                    toolsLog::order_createOrder_warning('提交订单创建子订单数据失败', $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => "提交订单创建子订单数据失败:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }

                //目前是门店自提才会默认有包裹信息
                if (!empty($orderPackage)) {
                    array_map(function ($v) use ($uid) {
                        $skuIds = trim(implode(',', $v['sku_id_list']), ',');
                        mOrderPackage::createPackage($uid, $v['order_no'], $skuIds, $v['express_company'], $v['express_no']);
                    }, $orderPackage);
                }
                $result = mOrderExtend::insertOrderExtend(array_values($orderExtendInsert));
                if (!$result) {
                    $errArr = [
                        'result' => $result,
                        'sql' => mOrderExtend::log(),
                        'data' => $orderExtendInsert,
                    ];
                    toolsLog::order_createOrder_warning('提交订单创建子订单扩展数据失败', $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => "提交订单创建子订单扩展数据失败:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
                $result = mOrderGoods::insertOrderGoods(array_values($orderGoodsInsert));
                if (!$result) {
                    $errArr = [
                        'result' => $result,
                        'sql' => mOrderGoods::log(),
                        'data' => $orderGoodsInsert,
                    ];
                    toolsLog::order_createOrder_warning('提交订单创建订单商品数据失败', $errArr);
                    Queue::insertQueue("queue/Wechatnotice/toTag", [
                        "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                        "content" => "提交订单创建订单商品数据失败:" . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
                    ], Queue::QUEUE_BIZ);
                    throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
            } else {
                toolsLog::order_createOrder_warning('提交订单创建订单数据失败', [
                    'orderParentInsert' => $orderParentInsert,
                    'orderInsert' => $orderInsert,
                    'orderGoodsInsert' => $orderGoodsInsert,
                ]);
                Queue::insertQueue("queue/Wechatnotice/toTag", [
                    "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                    "content" => "提交订单创建订单数据失败:" . "#params:" . json_encode([
                            'orderParentInsert' => $orderParentInsert,
                            'orderInsert' => $orderInsert,
                            'orderGoodsInsert' => $orderGoodsInsert,
                        ], JSON_UNESCAPED_UNICODE)
                ], Queue::QUEUE_BIZ);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
            //订单创建成功数据
            $orderResult = [
                'uid' => $uid,
                'order_parent_no' => $orderPno,
                'order_parent_info' => $orderParentInsert,
                'order_list' => $orderInsert,
                'order_goods_list' => $orderGoodsInsert,
            ];
            return $orderResult;
        });
        if ($result !== false) {
            return $result;
        } else {
            self::createOrderFail($uid, $orderPno, $orders, $shopIntegralArr, $shopRedPacketArr, $couponId, $couponVid, $shopCouponList, $groupInsert);
            return false;
        }
    }

    private static function checkInsertOrderData($uid, $orderParentInsert, $orderInsert, $orderGoodsInsert)
    {
        $orderAllPayAmount = 0;
        $goodsAllPayAmount = [];
        $goodsAllCommissions = [];
        $goodsAllShippingAmount = [];
        $checkGoodsPayAmount['code'] = true;
        $checkGoodsCommissions['code'] = true;
        $checkOrderPayAmount['code'] = true;
        $checkOrderCommissions['code'] = true;
        $checkOrderShippingAmount['code'] = true;
        foreach ($orderGoodsInsert as $skuId => $skuInfo) {
            $shopId = $skuInfo['shop_id'];
            $checkGoodsPayAmount = OrderAmount::checkGoodsPayAmount($skuId, $skuInfo['pay_amount'], $skuInfo['goods_amount'], $skuInfo['integral_amount'], $skuInfo['packet_amount'], $skuInfo['coupon_amount'], $skuInfo['s_coupon_amount'], $skuInfo['meal_amount']);
            $checkGoodsCommissions = OrderAmount::checkGoodsCommissions($skuId, $skuInfo['sell_price'], $skuInfo['buy_price'], $skuInfo['buy_num'], $skuInfo['promo_type'], $skuInfo['commissions'], $skuInfo['goods_amount'], $skuInfo['activity_allowance'], $skuInfo['s_coupon_amount'], $skuInfo['meal_amount'], $skuInfo['commission_rate']);
            if (!isset($goodsAllPayAmount[$shopId])) {
                $goodsAllPayAmount[$shopId] = 0;
            }
            if (!isset($goodsAllCommissions[$shopId])) {
                $goodsAllCommissions[$shopId] = 0;
            }
            if (!isset($goodsAllShippingAmount[$shopId])) {
                $goodsAllShippingAmount[$shopId] = 0;
            }
            $goodsAllPayAmount[$shopId] = bcadd($goodsAllPayAmount[$shopId], $skuInfo['pay_amount'], 2);
            $goodsAllCommissions[$shopId] = bcadd($goodsAllCommissions[$shopId], $skuInfo['commissions'], 2);
            $goodsAllShippingAmount[$shopId] = bcadd($goodsAllShippingAmount[$shopId], $skuInfo['shipping_amount'], 2);
        }
        foreach ($orderInsert as $shopId => $orderInfo) {
            $orderAllPayAmount = bcadd($orderAllPayAmount, $orderInfo['pay_amount'], 2);
            $checkOrderPayAmount = OrderAmount::checkOrderAndGoodsPayAmount($goodsAllPayAmount[$shopId], $orderInfo['pay_amount'], $orderInfo['shipping_amount']);
            $checkOrderCommissions = OrderAmount::checkOrderAndGoodsCommissions($goodsAllCommissions[$shopId], $orderInfo['commissions']);
            $checkOrderShippingAmount = OrderAmount::checkOrderAndGoodsShippingAmount($shopId, $goodsAllShippingAmount[$shopId], $orderInfo['shipping_amount'], 2);
        }
        $checkParentAmount = OrderAmount::checkOrderParentPayAmount($orderAllPayAmount, $orderParentInsert['pay_amount']);
        if ($checkParentAmount['code'] && $checkGoodsPayAmount['code'] && $checkGoodsCommissions['code'] && $checkOrderPayAmount['code'] && $checkOrderCommissions['code'] && $checkOrderShippingAmount['code']) {
            return true;
        } else {
            $msg = '检查支付金额错误';
            $errArr = [
                'orderParentInsert' => $orderParentInsert,
                'orderInsert' => $orderInsert,
                'orderGoodsInsert' => $orderGoodsInsert,
            ];
            if (!$checkParentAmount['code']) {
                $msg = $checkParentAmount['msg'];
                $errArr = $checkParentAmount['errArr'];
            }
            if (!$checkGoodsPayAmount['code']) {
                $msg = $checkGoodsPayAmount['msg'];
                $errArr = $checkGoodsPayAmount['errArr'];
            } else if (!$checkGoodsCommissions['code']) {
                $msg = $checkGoodsCommissions['msg'];
                $errArr = $checkGoodsCommissions['errArr'];
            } else if (!$checkOrderPayAmount['code']) {
                $msg = $checkOrderPayAmount['msg'];
                $errArr = $checkOrderPayAmount['errArr'];
            } else if (!$checkOrderCommissions['code']) {
                $msg = $checkOrderCommissions['msg'];
                $errArr = $checkOrderCommissions['errArr'];
            } else if (!$checkOrderShippingAmount['code']) {
                $msg = $checkOrderShippingAmount['msg'];
                $errArr = $checkOrderShippingAmount['errArr'];
            }
            $errArr['uid'] = $uid;
            toolsLog::order_createOrder_warning($msg, $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => $msg . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            toolsLog::order_createOrder_warning('提交订单创建订单数据失败', [
                'orderParentInsert' => $orderParentInsert,
                'orderInsert' => $orderInsert,
                'orderGoodsInsert' => $orderGoodsInsert,
            ]);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "提交订单创建订单数据失败:" . "#params:" . json_encode([
                        'orderParentInsert' => $orderParentInsert,
                        'orderInsert' => $orderInsert,
                        'orderGoodsInsert' => $orderGoodsInsert,
                    ], JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
        }

    }

    public static function createOrderFail($uid, $orderParentNo, $orders, $shopIntegralArr, $shopRedPacketArr, $couponId, $couponVid, $shopCouponList, $groupInsert)
    {
        self::_async($uid, $orderParentNo, $orders, $shopIntegralArr, $shopRedPacketArr, $couponId, $couponVid, $shopCouponList, $groupInsert);
    }

    public static function _async_createOrderFail($uid, $orderParentNo, $orders, $shopIntegralArr, $shopRedPacketArr, $couponId, $couponVid, $shopCouponList, $groupInsert)
    {
        $orderNos = array_values($orders);

        foreach ($orderNos as $shopId => $orderNo) {
            Event::push(Event::ORDER_CREATE_FAIL, [
                'uid' => $uid,
                'order_no' => $orderNo,
                'shop_id' => $shopId,
                'uniq_idx' => ['order_no', 'event_tag']
            ]);
        }


        sStock::IncrStockByOrderNos($orderNos);
        foreach ($shopIntegralArr as $row) {
            sIntegral::operatePoint($uid, $row['integral'], $row['order_no'], 2);
        }
        foreach ($shopRedPacketArr as $row) {
            sRedPackets::cancelInOrder($uid, $row['order_no'], $row['packet_amount']);
        }
        if ($couponId && $couponVid) {
            clsCoupon::cancelACouponInOrder($uid, $orderParentNo, $couponId, $couponVid);
        }
        if ($shopCouponList) {
            foreach ($shopCouponList as $shopId => $shopCouponInfo) {
                clsShopCoupon::cancelAShopCouponInOrder($uid, $shopId, $shopCouponInfo['order_no'], $shopCouponInfo['coupon_id'], $shopCouponInfo['coupon_vid']);
            }
        }

        if ($groupInsert) {
            //删除拼团信息
            sGroup::createOrderFail($orderNo);
        }
    }


    /**
     * 下单成功后操作
     * @param $uid
     * @param $orderResult 订单数据
     * @param $source 订单来源 购物车或则立即购买
     * @param $appType app来源
     * @throws \Exception
     */
    public static function afterCreateOrder($uid, $orderResult, $source, $appType)
    {
        //结算流程
        foreach ($orderResult['order_list'] as $shopId => $orderInfo) {
            if (floatval($orderInfo['integral_amount']) || floatval($orderInfo['coupon_amount']) || floatval($orderInfo['activity_allowance']) || floatval($orderInfo['packet_amount'])) {//结算流程
                SettlementTransaction::afterCreateOrder($shopId, $orderInfo['order_no'], $orderInfo['integral_amount'], $orderInfo['coupon_amount'], $orderInfo['activity_allowance'], $orderInfo['packet_amount']);
            }
        }
        self::_async($uid, $orderResult, $source, $appType);
    }

    public static function _async_afterCreateOrder($uid, $orderResult, $source, $appType)
    {
        $orderSkuList = [];
        foreach ($orderResult['order_goods_list'] as $skuId => $skuInfo) {
            $orderSkuList[$skuInfo['order_no']][] = $skuInfo;
        }
        $orderList = [];
        foreach ($orderResult['order_list'] as $shopId => $orderInfo) {
            $skuList = $orderSkuList[$orderInfo['order_no']];
            $orderList[] = [
                'order_no' => $orderInfo['order_no'],
                'shop_info' => ['shop_id' => $orderInfo['shop_id']],
                'sku_list' => $skuList
            ];

        }

        sSalesOrder::createSalesOrder($orderResult['order_goods_list'], $appType);


        Event::push(Event::ORDER_CREATE_SUCCESS, [
            'uid' => $uid,
            'from_source' => $source,
            'order_parent_no' => isset($orderInfo['order_parent_no']) ? $orderInfo['order_parent_no'] : '',
            'order_list' => $orderList,
            'uniq_idx' => ['order_parent_no', 'event_tag']
        ], self::$eventId);

    }

    private static function createSkuToken($uid, $cacheData)
    {
        ConfirmOrderCache::delConfirmInfo($uid);
        $skuToken = md5(str_shuffle(microtime()));
        ConfirmOrderCache::setConfirmInfo($uid, $skuToken, json_encode($cacheData));
        return $skuToken;
    }

    private static function checkConfirmSku($uid, $skuNumList, $skuInfoList, $mealId, $activityId, $activityType, $teamJoinId)
    {
        $skuNumIds = array_keys($skuNumList);
        $skuIds = array_keys($skuInfoList);
        if (array_diff($skuNumIds, $skuIds)) {//sku信息不存在
            toolsLog::order_confirmOrderList_warning('结算订单skuId不一致', [
                'submit_sku_Ids' => $skuNumIds,
                'sku_Ids' => $skuIds,
            ]);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);
        }
        $goodsBuyNumList = [];
        $shopIds = [];
        foreach ($skuInfoList as $skuId => $skuInfo) {//
            if ($skuInfo['status'] != mGoodsSku::STATUS_PASSED) {//sku状态不正确
                toolsLog::order_confirmOrderList_warning('sku状态不正确', [
                    'sku_Id' => $skuId,
                    'goods_id' => $skuInfo['goods_info']['goods_id'],
                    'status' => $skuInfo['status'],
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);
            }
            if ($skuInfo['goods_info']['status'] != mGoodsBasicInfo::STATUS_APP_NOMAL) {//商品失效
                toolsLog::order_confirmOrderList_warning('商品状态不正确', [
                    'sku_id' => $skuId,
                    'goods_id' => $skuInfo['goods_info']['goods_id'],
                    'status' => $skuInfo['goods_info']['status'],
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_GOODS_NO_STOCK], ErrorConst::ERROR_GOODS_NO_STOCK);
            }
            if ($skuInfo['actual_stock'] < $skuNumList[$skuId]) {//库存不足
                toolsLog::order_confirmOrderList_warning('sku库存不足', [
                    'sku_Id' => $skuId,
                    'goods_id' => $skuInfo['goods_info']['goods_id'],
                    'actual_stock' => $skuInfo['actual_stock'],
                    'submit_stock' => $skuNumList[$skuId]
                ]);
                throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_SKU_NO_STOCK], ErrorConst::ERROR_SKU_NO_STOCK);
            }

            if (isset($skuInfo['limit_buy_count']) && $skuInfo['limit_buy_count']) {//限购数量
                $goodsBuyNumList[$skuInfo['goods_id']]['limit_buy_count'] = $skuInfo['limit_buy_count'];
                if (!isset($goodsBuyNumList[$skuInfo['goods_id']]['buy_num'])) {
                    $goodsBuyNumList[$skuInfo['goods_id']]['buy_num'] = 0;
                }
                if (!isset($goodsBuyNumList[$skuInfo['goods_id']]['sku_num_list'])) {
                    $goodsBuyNumList[$skuInfo['goods_id']]['sku_num_list'] = [];
                }
                $goodsBuyNumList[$skuInfo['goods_id']]['buy_num'] += $skuNumList[$skuId];
                $goodsBuyNumList[$skuInfo['goods_id']]['sku_num_list'][] = ['sku_id' => $skuId, 'buy_num' => $skuNumList[$skuId]];
                $goodsBuyNumList[$skuInfo['goods_id']]['title'] = $skuInfo['goods_info']['title'];
                $goodsBuyNumList[$skuInfo['goods_id']]['promo_id'] = isset($skuInfo['activity_id']) ? $skuInfo['activity_id'] : 0;
            }
            $shopIds[] = $skuInfo['shop_id'];
        }

        $shopIds = array_unique($shopIds);
        if ($mealId && count($shopIds) > 1) {//目前套餐下单不支持跨店铺
            $errArr = [
                'uid' => $uid,
                'meal_id' => $mealId,
                'shop_ids' => $shopIds,
                'sku_num_list' => $skuNumList
            ];
            toolsLog::order_confirmOrderList_warning('套餐下单只能支持单个店铺', $errArr);
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                "content" => "获取确认订单信息失败，套餐下单只能支持单个店铺:#date:" . date('YmdHis') . "#params:" . json_encode($errArr, JSON_UNESCAPED_UNICODE)
            ], Queue::QUEUE_BIZ);
            throw new \Exception(ErrorConst::$errorDesc[ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA], -1);
        }
        if ($activityId && $activityType && $activityType == constActivityInfo::ACTIVITY_TYPE_PINTUAN) {//拼团限制
            try {
                sGroup::checkGroup($uid, $skuNumIds[0], $teamJoinId);
            } catch (\Exception $e) {
                $msg = $e->getMessage();
                $errArr = [
                    'uid' => $uid,
                    'sku_id' => $skuNumIds[0],
                    'team_join_id' => $teamJoinId
                ];
                toolsLog::order_confirmOrderList_warning('确认订单页拼团失败#' . $msg . '#file' . $e->getFile() . '#line' . $e->getLine(), $errArr);
                throw new \Exception($msg, ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
            }
        } else {
            //是否限购1.spu数量 2.已下单（待付款，或则付过款）spu数量  是否<限购数量
            foreach ($goodsBuyNumList as $goodsId => $row) {
                $errorArr = [
                    'uid' => $uid,
                    'sku_buy_num_list' => $row['sku_num_list'],
                    'goods_id' => $goodsId,
                    'title' => $row['title'],
                    'goods_buy_num' => $row['buy_num'],
                    'limit_buy_count' => $row['limit_buy_count'],
                ];
                if ($row['limit_buy_count'] && $row['buy_num'] > $row['limit_buy_count']) {
                    toolsLog::order_confirmOrderList_warning('商品限购数量不正确', $errorArr);
                    throw new \Exception('「' . $row['title'] . '」限购' . $row['limit_buy_count'] . '件', ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                }
            }
            if ($goodsBuyNumList) {
                //查询已下订单商品
                $goodsNums = self::getLimitGoodsOrderNum($uid, $goodsBuyNumList);
                toolsLog::order_confirmOrderList_debug('下单商品查询', compact('goodsBuyNumList', 'goodsNums', 'skuInfoList'));
                foreach ($goodsNums as $goodsId => $row) {
                    $promoId = 0;
                    if (isset($goodsBuyNumList[$goodsId]['promo_id'])) {
                        $promoId = $goodsBuyNumList[$goodsId]['promo_id'];
                    }
                    $num = isset($row[$promoId]) ? $row[$promoId] : 0;
                    $limitCount = $goodsBuyNumList[$goodsId]['limit_buy_count'];
                    $title = $goodsBuyNumList[$goodsId]['title'];
                    $errorArr = [
                        'uid' => $uid,
                        'goods_id' => $goodsId,
                        'title' => $title,
                        'promo_id' => $promoId,
                        'goods_buy_num' => $num, //加上此次购买,总的购买数量
                        'limit_buy_count' => $limitCount,
                    ];
                    if ($promoId && $limitCount && $num > $limitCount) {
                        toolsLog::order_confirmOrderList_warning('商品限购数量不正确,已购买或则已下过单', $errorArr);
                        Queue::insertQueue("queue/Wechatnotice/toTag", [
                            "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_ORDER,
                            "content" => "商品限购数量不正确,已购买或则已下过单:" . "#params:" . json_encode($errorArr, JSON_UNESCAPED_UNICODE)
                        ], Queue::QUEUE_BIZ);
                        throw new \Exception('「' . $title . '」限购' . $limitCount . '件', ErrorConst::ERROR_ORDER_CREATE_ORDER_DATA);
                    }
                }
            }
        }
    }

    public static function afterConfirmOrderSettlement($shopId, $orderNo, $payAmount, $integralAmount, $couponAmount, $activityAllowance, $packetAmount, $commissions, $payWay, $shippingAmount, $confirmTime, $isSys = false)
    {

        $refundSuccessSum = mOrderRefundQueue::select([
            'rmb' => Medoo::raw('SUM(refund_rmb+refund_shipping_amount)'),
            'shipping_amount' => Medoo::raw('SUM(refund_shipping_amount)'),
            'integral_amount' => Medoo::raw('SUM(refund_integral_amount)'),
            'packet_amount' => Medoo::raw('SUM(refund_packet_amount)'),
            'coupon_amount' => Medoo::raw('SUM(refund_coupon_amount)'),
            'activity_allowance' => Medoo::raw('SUM(refund_activity_allowance)'),
            'commissions' => Medoo::raw('SUM(refund_commission_amount)'),
        ], ['order_no' => $orderNo]);

        $refundSuccessSum = array_shift($refundSuccessSum);


        //订单结算流程
        $transactionAmount = !empty($refundSuccessSum['rmb']) ? ($payAmount - $refundSuccessSum['rmb']) : $payAmount;
        $integralAmount = !empty($refundSuccessSum['integral_amount']) ? ($integralAmount - $refundSuccessSum['integral_amount']) : $integralAmount;
        $packetAmount = !empty($refundSuccessSum['packet_amount']) ? ($packetAmount - $refundSuccessSum['packet_amount']) : $packetAmount;
        $couponAmount = !empty($refundSuccessSum['coupon_amount']) ? ($couponAmount - $refundSuccessSum['coupon_amount']) : $couponAmount;
        $activityAllowance = !empty($refundSuccessSum['activity_allowance']) ? ($activityAllowance - $refundSuccessSum['activity_allowance']) : $activityAllowance;
        $commissions = !empty($refundSuccessSum['commissions']) ? ($commissions - $refundSuccessSum['commissions']) : $commissions;
        $shippingAmount = !empty($refundSuccessSum['shipping_amount']) ? ($shippingAmount - $refundSuccessSum['shipping_amount']) : $shippingAmount;

        SettlementTransaction::afterConfirmOrder($shopId, $orderNo, $transactionAmount, $integralAmount, $couponAmount, $activityAllowance, $packetAmount, $commissions, $payWay, $shippingAmount, $confirmTime, $isSys);

    }

    //如果是最后一个订单取消，那么则退优惠券
    public static function lastCancelOrderWithCancelCoupon($uid, $orderNo)
    {

        $parentOrderNo = str_replace('/-\d$/', '/-P/', $orderNo);

        $orderList = mOrder::select(['order_no', 'coupon_id', 'coupon_vid', 'status'], ['order_parent_no' => $parentOrderNo]);


        $noCloseList = array_filter($orderList, function ($v) {

            if ($v['status'] != mOrder::STATUS_CLOSE) {
                return true;
            }

            return false;
        });


        if (empty($noCloseList)) {

            $couponId = array_shift(array_column($orderList, 'coupon_id', 'coupon_id'));
            $couponVid = array_shift(array_column($orderList, 'coupon_vid', 'coupon_vid'));

            return clsCoupon::cancelACouponInOrder($uid, $parentOrderNo, $couponId, $couponVid);

        }

        return false;

    }

    public static function getOrderFromSource($appType)
    {
        switch ($appType) {
            case AppType::APPTYPE_IOS:
            case AppType::APPTYPE_ANDROID:
                $fromSource = mOrder::FROM_SOURCE_APP;
                break;
            case AppType::APPTYPE_MINIPROGRAM:
                $fromSource = mOrder::FROM_SOURCE_WX_MINI;
                break;
            case AppType::APPTYPE_TUAN_MINIPROGRAM:
                $fromSource = mOrder::FROM_SOURCE_TUAN_MINI;
                break;
            case AppType::APPTYPE_PARAGRAPH_MINIPROGRAM:
                $fromSource = mOrder::FROM_SOURCE_PARAGRAPH_MINIPROGRAM;
                break;
            default:
                $fromSource = mOrder::FROM_SOURCE_APP;
                break;
        }
        return $fromSource;
    }

    private static function getOrderType($fromSource, $activityType = 0)
    {
        if ($fromSource == mOrder::FROM_SOURCE_TUAN_MINI) {
            $orderType = mOrder::ORDER_TYPE_GROUP_BUY;
        } else {
            $orderType = mOrder::ORDER_TYPE_NORMAL;
        }
        if ($activityType == constActivityInfo::ACTIVITY_TYPE_PINTUAN) {
            $orderType = mOrder::ORDER_TYPE_PING_TUAN;
        }
        return $orderType;
    }

    /**
     * 获取限购商品订单中商品（已下单商品）数量  todo 优化，库存日志表获取
     * 待付款和已付款的订单商品
     * @param $uid
     * @param array $goodsBuyNumList
     * @return array
     */
    public static function getLimitGoodsOrderNum($uid, $goodsBuyNumList)
    {
        $goodsIds = array_keys($goodsBuyNumList);
        $list = mOrderGoods::getUserOrdersByGoodsId($uid, $goodsIds, ['promo_id', 'order_no', 'goods_id', 'sku_id', 'buy_num']);

        $orderNos = array_column($list, 'order_no');
        $where = [
            'AND' => [
                'uid' => $uid,
                'order_no' => $orderNos,
                'OR' => [
                    'status' => [mOrder::STATUS_NORMAL],
                    'pay_no[!]' => '',
                ]
            ]
        ];
        $orderList = mOrder::getOrderInfoList($where, [], [], false, ['order_no']);
        $orderNos = $orderList ? array_column($orderList, 'order_no') : [];

        $goodsBuyNum = [];
        $promoIds = [];
        foreach ($goodsBuyNumList as $goodsId => $buyNumInfo) {
            $promoId = $buyNumInfo['promo_id'];
            $promoIds[] = $promoId;
            if (isset($goodsBuyNum[$goodsId][$promoId])) {
                $goodsBuyNum[$goodsId][$promoId] += $buyNumInfo['buy_num'];
            } else {
                $goodsBuyNum[$goodsId][$promoId] = $buyNumInfo['buy_num'];
            }
        }

        foreach ($list as $row) {
            $promoId = $row['promo_id'];
            $orderNo = $row['order_no'];
            if (in_array($orderNo, $orderNos) && in_array($promoId, $promoIds)) {
                if (isset($goodsBuyNum[$row['goods_id']][$promoId])) {
                    $goodsBuyNum[$row['goods_id']][$promoId] += $row['buy_num'];
                } else {
                    $goodsBuyNum[$row['goods_id']][$promoId] = $row['buy_num'];
                }
            }
        }

//        foreach ($goodsBuyNumList as $goodsId => $buyNumInfo) {
//            $promoId = $buyNumInfo['promo_id'];
//            if (!isset($goodsBuyNum[$goodsId][$promoId]) && $promoId) {
//                $goodsBuyNum[$goodsId][$promoId] = 0;
//            }
//            if (isset($orderGoodsList[$goodsId])) {
//                foreach ($orderGoodsList[$goodsId] as $row) {
//                    $orderNo = $row['order_no'];
//                    if (in_array($orderNo, $orderNos) && $row['promo_id'] == $promoId) {
//                        $goodsBuyNum[$goodsId][$promoId] += $row['buy_num'];
//                    }
//                }
//            }
//        }
        return $goodsBuyNum;
    }

    private static function confirmStruct()
    {
        //accept_info 展示默认收货地址
        $accept_info = new \stdClass();
        $accept_info->id = 0;           //地址簿id
        $accept_info->accept_name = ''; //收货人姓名
        $accept_info->mobile = '';      //收货人手机号
        $accept_info->province = '';    //省code
        $accept_info->address = '';     //收货详细地址
        $accept_info->accept_tip = [    //地址提示信息
            'icon' => '',               //提示信息icon
            'text' => '',               //提示信息text
        ];
        //list 购买列表
        $shopList = new \stdClass();
        $list = [
            &$shopList
        ];
        $shopList->shop_info = [
            'shop_id' => 0,     //店铺id
            'shop_name' => '',  //店铺名称
            'imgurl' => '',     //店铺图像
        ];
        $shopList->sku_list = [     //店铺购买sku列表

        ];
        $shopList->summary = [      //店铺小计信息
            'total_buynum' => 0,    //店铺总购买数量
            'goods_amount' => 0,    //商品总额不包含运费
            'total_amount' => 0,    //店铺小计（包含商品金额和运费）
            'shipping_amount' => 0, //店铺运费
        ];
        $shopList->coupon = [       //店铺优惠券
            'coupon_vid' => '',
            'coupon_id' => '',
            'title' => '',
            'detract_amount' => '',
        ];
        $shopList->meal = [         //套餐信息
            'meal_id' => '',        //套餐id
            'detract_amount' => '', //套餐优惠金额
        ];
        $shopList->amount_struct = [    //金额map
            [
                'name' => '',             //名称
                'icon' => '',             //icon
                'text' => '',             //内容
                'type' => '',             //类型（1：正数2：负数）
            ],
        ];
    }

    /**
     * @param int $goodsRatio 商品自定义ratio
     * @param string $storeAbbr 店铺简称
     * @param bool $isDesigner 是否是设计师
     * @param string $goodsRatioExt 商品自定义ratio扩展（店铺，设计师ratio）
     * @return int
     */
    public static function getGoodsRatio($goodsRatio = 0, $storeAbbr = '', $isDesigner = false, $goodsRatioExt = '')
    {
        $ratio = null;
        $goodsRatioExt = $goodsRatioExt ? json_decode($goodsRatioExt, true) : [];
        if ($storeAbbr && $goodsRatioExt) {
            $key = $storeAbbr;
            if ($isDesigner) {
                $key = $storeAbbr . ShopCommissionRate::DESIGNER_SUFFIX;
                if (!isset($goodsRatioExt[$key]['ratio']) || $goodsRatioExt[$key]['ratio'] == '') {
                    $key = $storeAbbr;
                }
            }
            $ratio = isset($goodsRatioExt[$key]['ratio']) ? $goodsRatioExt[$key]['ratio'] : null;
            if (!is_null($ratio)) {
                if ($ratio == '') {
                    $ratio = $goodsRatio;
                }
            }
        } else if ($goodsRatio) {
            $ratio = $goodsRatio;
        }
        return $ratio;
    }

    public static function getCategoryRatio($cateGoryRatio, $storeAbbr = '', $isDesigner = false, $categoryRatioExt = '')
    {
        $ratio = $cateGoryRatio;
        $categoryRatioExt = $categoryRatioExt ? json_decode($categoryRatioExt, true) : [];
        if ($storeAbbr && $categoryRatioExt) {
            $key = $storeAbbr;
            if ($isDesigner) {
                $key = $storeAbbr . ShopCommissionRate::DESIGNER_SUFFIX;
                if (!isset($categoryRatioExt[$key]['ratio']) || $categoryRatioExt[$key]['ratio'] == '') {
                    $key = $storeAbbr;
                }
            }
            $ratio = isset($categoryRatioExt[$key]['ratio']) ? $categoryRatioExt[$key]['ratio'] : null;
            $ratio = empty($ratio) ? $cateGoryRatio : $ratio;
        }
        return $ratio;
    }

    public static function zyjtVersion()
    {
        $versionBool = version_compare(HhzClient::getClientVersion(), '4.6.5', '>=');
        $clientBool = in_array(HhzClient::getClientType(), [AppType::APPTYPE_IOS, AppType::APPTYPE_ANDROID]);
        return $clientBool && $versionBool;
    }

}